程序集 x86 中的整数除法

division between integers in assembly x86

我正在开发编译器,但在尝试从以下自定义语言代码生成汇编代码时遇到问题

b:=-2;
c:=-4;
a:=c/b;

为了测试这个结果,我使用 if 条件询问是否 == 2 但不是。

这是代码avobe生成的一段代码

mov ax, 1
mov _a, ax

mov ax, -2
mov _b, ax

mov ax, -4
mov _c, ax


mov dx, 0
mov ax, _c   
mov bx, _b
cmp bx, 0
JE label_div0Excp  // jump to division by 0 message
idiv bx  
mov @aux0, ax

mov ax, @aux0
mov _a, ax

mov ax, _a
cmp ax,2

JNE label_1

invoke MessageBox, NULL, addr _message0, addr _message0, MB_OK  //_message0 say that result == 2

有人可以帮我吗?

谢谢

IDIV 做带符号的除法,所以它期望 DX:AX 中的被除数是带符号的双字。因此,您应该将 AX 符号扩展为 DX:AX,而不是在除法之前清除 DX。这可以通过 CWD 指令来完成。

来自英特尔手册:"The CWD instruction can be used to produce a doubleword dividend from a word before word division."

IDIV BX 指令执行有符号DX:AX 除以BX。 DX:AX 是两个 16 位寄存器粘合在一起并被视为一个 32 位值。您已将 DX 归零,但将 DX 归零不足以进行有符号算术运算。您需要签署扩展 AX 到 DX。换句话说,如果 AX 为正数,则 DX 应为 0,但如果 AX 为负数,则 DX 需要为 -1,即 0xFFFF。方便的是,有一条指令可以在不进行显式比较或跳转的情况下执行此符号扩展:CWD (convert word to d双).

试试这个:

mov ax, _c   
cwd              //  <--------------
mov bx, _b
cmp bx, 0
JE label_div0Excp  // jump to division by 0 message
idiv bx