不使用asm sub和sbb进行64位减法?

时间:2014-03-30 12:02:51

标签: assembly x86 intel pascal

我有一个问题,如何在不使用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验证结果时,它是正确且合乎逻辑但不等于上面。那么我做错了什么?请帮忙。

2 个答案:

答案 0 :(得分:3)

你不能NEG这两个部分的数字,并期望得到正确的结果。示例:-1 = 0xFFFFFFFF 0xFFFFFFFF如果您将NEG应用于两半,则会得到0x00000001 0x00000001,这显然是错误的。您需要应用翻转所有位并添加一个的一般规则,例如:

not ecx
not edx
add ecx, 1
adc edx, 0

此外,我认为作业只是希望您使用addadc,您不必自己处理。

答案 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