我正在开发编译器,当我尝试从以下自定义语言代码生成汇编代码时出现问题
b:=-2;
c:=-4;
a:=c/b;
测试这个结果我使用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
enybody可以帮助我吗?
感谢
答案 0 :(得分:7)
IDIV
签署了分部,因此它希望DX:AX
中的股息是一个有符号的双字。因此,您不应在分割前清除DX
,而应将AX
签名延伸到DX:AX
。这可以使用CWD
指令完成。
从英特尔手册:“CWD
指令可用于在分词前从单词产生双字红利。”
答案 1 :(得分:5)
IDIV BX
指令通过DX:AX
执行签名除以BX
。 DX:AX是两个粘在一起的16位寄存器,被视为一个32位值。您已将DX归零,但将DX归零对于已签名的算术来说是不够的。您需要签署扩展 AX到DX。换句话说,如果AX
为正,DX
应为0,但如果AX
为负,则DX
需要为-1,即0xFFFF。方便的是,有一条指令执行此符号扩展而没有明确的比较或跳转:CWD
( c 转换 w ord转换为 d ouble)。
请改为尝试:
mov ax, _c
cwd // <--------------
mov bx, _b
cmp bx, 0
JE label_div0Excp // jump to division by 0 message
idiv bx