x86装配GAS部门

我还不太确定x86组件(GAS AT&T语法)如何工作。 我想要做的是将两个长分开,然后将商与除数相乘以查看新数是否等于初始数(n / m * m = n)。

movl %ebx, %eax
movl %ecx, %edx
idivl %edx
imull %ebx, %edx

cmp %edx, %ebx
je .equal

上面的代码是我做分区的一个片段。 ebx和ecx是我想要分割的两个计数器,eax寄存器用作除数是否正确? 所以当我写idivl%edx我将edx和eax分开,并且我得到的整数最接近0? 像7/2 = 3? 我读了一个地方,商是存储在edx寄存器中,其余部分存储在ah寄存器中,但我也被告知商存储在eax寄存器中,其余部分存储在edx寄存器中,这让我感到困惑。

尽管这里的主要问题是:我想将ebx寄存器的值与ecx寄存器的值分开,我应该如何继续?

谢谢!

编辑:上面的代码产生浮点异常


idiv指令在3个寄存器中有2个参数。
第一个隐含的论点是股息, edx:eax的64位参数
低32位在eax ,高32位在edx
第二个明确的参数是除数,32位参数在一个寄存器中。
由于显而易见的原因除数应该edxeax
结果以eax = Quotient,edx = Remainder的形式返回。

知道这个适当的设置应该是:

Intel syntax                    pdp-11 syntax
--------------------------------------------------------
.intel_syntax noprefix
mov ebx, dividend
mov ecx, divisor

mov eax,ebx                     movl %ebx, %eax     
cdq                             cdq                 //edx:eax = 32 bit dividend 
idiv ecx                        idivl %ecx          //divide edx:eax by ecx
imul eax, ecx                   imull %ecx, %eax    //multiply result by dividend
cmp ebx, eax                    cmpl %eax, %ebx
je .equal                       je .equal
add eax,edx                     addl %edx, %eax     //add remainder
cmp ebx,eax                     cmpl %eax,%ebx      //should be equal now
je .equal2                      je .equal2

你应该记住div/idiv执行整数除法!
结果总是一个剩余的整数(可能为零)。

它没有做任何浮点。 如果结果太大而无法放入32位或者除以零,则只会生成一个异常,在这种情况下会出现#DE分区错误。
你得到一个整数除法错误的原因是你错误地使用了edx作为除数,并且因为你的分配是32位,所以高32位(存储在edx )总是为零,因此你除以零。
切勿使用相同的寄存器进行分红和除数!
如果edx:eax idiv ecx不适合32位(即,如果edx:eax相对于ecx太大),则会得到相同的错误。

请参阅:http://www.felixcloutier.com/x86/IDIV.html和http://www.felixcloutier.com/x86/DIV.html

我对ATT(又名PDP语法)嗤之以鼻,这种语法是荒谬的,也是破碎的。
您可以使用.intel_syntax noprefix伪指令来恢复完整性并在Gas中使用Intel语法。
请参阅:我能否使用GCC的x86汇编语言?

链接地址: http://www.djcxy.com/p/89851.html

上一篇: Division in x86 Assembly GAS

下一篇: I am trying to program finite state machine in assembly language but i am stuck