程序集x86中的整数之间的划分

luc*_*cas 2 x86 assembly masm

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

b:=-2;
c:=-4;
a:=c/b;
Run Code Online (Sandbox Code Playgroud)

为了测试这个结果,我使用if条件询问a == 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
Run Code Online (Sandbox Code Playgroud)

enybody可以帮助我吗?

谢谢

Mic*_*ael 7

IDIV签署分部,所以它希望股息DX:AX是一个签名的双字.而不是清除DX之前的划分,你应该因此符号扩展AXDX:AX.这可以通过CWD指令完成.

来自英特尔的手册:"该CWD指令可用于在分词之前从单词产生双字红利."


I. *_*edy 5

IDIV BX指令做了签署的鸿沟DX:AXBX.DX:AX是两个粘在一起的16位寄存器,被视为一个32位值.您已将DX归零,但将DX归零对于已签名的算术来说是不够的.您需要 AX 扩展为DX.换句话说,如果AX是正数,DX则应为0,但如果AX为负,则DX需要为-1,即0xFFFF.方便地,有执行此符号扩展没有明确的比较或跳转指令: CWD(ç onvert 瓦特 ORD到d ouble).

试试这个:

mov ax, _c   
cwd              //  <--------------
mov bx, _b
cmp bx, 0
JE label_div0Excp  // jump to division by 0 message
idiv bx
Run Code Online (Sandbox Code Playgroud)