尔湾的WriteDec http://programming.msjc.edu/asm/help/index.html?page=source%2Firvinelib%2Fwritedec.htm应替换为WriteInt http://programming.msjc.edu/asm/help/index.html?page=source%2Firvinelib%2Fwriteint.htm它处理参数EAX
作为签名号码。
在CPU内部,负数“-2”和正数“4294967294”被转换为相同的值:0xFFFFFFFE。DIV http://x86.renejeschke.de/html/file_module_x86_id_72.html正向执行除法 6/-2 (6/4294967294) 并得到结果 0 = 0x00000000,其中IDIV http://x86.renejeschke.de/html/file_module_x86_id_137.html结果是正确的:-3 = 0xFFFFFFFD。
MUL http://x86.renejeschke.de/html/file_module_x86_id_210.html and IMUL http://x86.renejeschke.de/html/file_module_x86_id_138.html结果的高部分不同(EDX
)。由于在这种情况下不需要高部分,因此不强制使用IMUL http://x86.renejeschke.de/html/file_module_x86_id_138.html.
没有不同的版本ADD http://x86.renejeschke.de/html/file_module_x86_id_5.html and SUB http://x86.renejeschke.de/html/file_module_x86_id_308.html对于有符号和无符号的数字。这是引入2的补码编码的主要原因。这只是一个解释:如果程序员决定这应该是一个有符号数,那么它就是一个有符号数。如果他/她/它决定这是一个无符号数,那么它就是一个无符号数。 CPU 不关心这些事情——结果总是一样的。
这是一个例子WriteInt http://programming.msjc.edu/asm/help/index.html?page=source%2Firvinelib%2Fwriteint.htm, IDIV http://x86.renejeschke.de/html/file_module_x86_id_137.html and IMUL http://x86.renejeschke.de/html/file_module_x86_id_138.html:
; ((A + B) / C) * ((D - A) + E)
INCLUDE Irvine32.inc
.DATA
valA dword 5
valB dword 4
valC dword 3
valD dword 2
valE dword 1
.CODE
main PROC
mov ecx, valA
add ecx, valB
mov edx, valC
call Divide
mov ecx, eax
mov edx, valD
sub edx, valA
add edx, valE
call Multiply
call WriteInt ; Write a positive or negative number
exit
main ENDP
Divide PROC USES ECX EDX ; EAX = ECX / EDX
mov eax, ecx
mov ecx, edx
xor edx, edx
idiv ecx ; Signed division, e.g 6/-3 = -2
ret
Divide ENDP
Multiply PROC USES ECX EDX ; EAX = ECX * EDX
mov eax, edx
imul ecx ; Signed multiplication
ret
Multiply ENDP
END main
需要进行 2 的补码计算才能获得数字的绝对值。例如。 -2 的表示有两部分:符号('-')和绝对值('2')。获取绝对值的一个简单方法是查看符号位(数字的最左边的位),然后进行适当的跳转。计算本身仅通过以下方式执行NEG http://x86.renejeschke.de/html/file_module_x86_id_216.html.
示例为WriteDec http://programming.msjc.edu/asm/help/index.html?page=source%2Firvinelib%2Fwritedec.htm, IDIV http://x86.renejeschke.de/html/file_module_x86_id_137.html and IMUL http://x86.renejeschke.de/html/file_module_x86_id_138.html:
; ((A + B) / C) * ((D - A) + E)
INCLUDE Irvine32.inc
.DATA
valA dword 5
valB dword 4
valC dword 3
valD dword 2
valE dword 1
.CODE
main PROC
mov ecx, valA
add ecx, valB
mov edx, valC
call Divide
mov ecx, eax
mov edx, valD
sub edx, valA
add edx, valE
call Multiply
test eax, eax ; Set the flags according to (EAX AND EAX)
jns J1 ; Skip the next block if EAX is positive (no sign)
; EAX is negative
push eax ; Preserve EAX
mov al, '-' ; Write the letter '-'
call WriteChar ; http://programming.msjc.edu/asm/help/index.html?page=source%2Firvinelib%2Fwritechar.htm
pop eax ; Restore EAX
neg eax ; 2's complement
J1:
call WriteDec ; Write EAX as positive number
exit
main ENDP
Divide PROC USES ECX EDX ; EAX = ECX / EDX
mov eax, ecx
mov ecx, edx
xor edx, edx
idiv ecx ; signed division, e.g 6/-3 = -2
ret
Divide ENDP
Multiply PROC USES ECX EDX ; EAX = ECX * EDX
mov eax, edx
imul ecx ; signed multiplication
ret
Multiply ENDP
END main
下面是一个无需跳转即可获取 EAX 绝对值的算法:
cdq
xor eax, edx
sub eax, edx