我有一个问题,如何在不使用asm命令sub和sbb的情况下实现2个num的64位减法? c标志必须在过程中更改,以显示从一个寄存器到另一个寄存器!我使用Free Pascal IDE和内置Intel风格的汇编程序。 所以这就是我所做的:
//1 number
mov esi, 0f000000h //low part
mov edi, 0 //high part
//2 number
mov ecx, 0f000000h //l
mov edx, 0 //h
//neg 2 num
neg ecx //0f1000000h -> ecx
neg edx
//1 num l part + (- 2 num l part)
add esi, ecx //0 -> esi, c=1!
//c -> eax
mov eax, 0
lahf
mov al, ah
mov ah, 0
and al, 1
neg eax //0ffffffffh -> eax
//1 num h part + (- 2 num h part)
add edi, edx
//1 num h part + (- c flag)
add edi, eax //0ffffffffh -> edi, s flag = 1
//verify result
mov esi, 0f000000h
mov edi, 0
mov ecx, 0f000000h
mov edx, 0
sub esi, ecx //c=0!
sbb edi, edx
当我尝试使用sub和sbb验证结果时,它是正确且合乎逻辑但不等于上面。那么我做错了什么?请帮忙。
答案 0 :(得分:3)
你不能NEG
这两个部分的数字,并期望得到正确的结果。示例:-1
= 0xFFFFFFFF 0xFFFFFFFF
如果您将NEG
应用于两半,则会得到0x00000001 0x00000001
,这显然是错误的。您需要应用翻转所有位并添加一个的一般规则,例如:
not ecx
not edx
add ecx, 1
adc edx, 0
此外,我认为作业只是希望您使用add
和adc
,您不必自己处理。
答案 1 :(得分:0)
好的,感谢所有想要帮助的人,我想拥抱你们所有人^。^所以这里的解决方案:
//1 num
mov eax, 0 //l
mov ebx, 0 //h
//2 num
mov ecx, 1 //l
mov edx, 0 //h
//2 num -> 2's complement
not ecx
not edx
add ecx, 1
adc edx, 0
//1 num + (- 2 num)
add eax, ecx
adc ebx, edx