程序集MASM处理负整数 [英] Assembly MASM Dealing with Negative Integers
问题描述
我被指示要编写一个程序集,该程序将执行以下算术运算:
I was instructed to write a program in assembly that will carry out the following arithmetic:
(((A + B)/C)*((D-A)+ E)
((A + B) / C) * ((D - A) + E)
当没有负值出现时,我已成功完成此操作,但假设A = 5,B = 4,C = 3,D = 2和E =1.这给出了((5 + 4 )/3)*((2-5)+1)或-6.
I've succeeded in doing this when no negative values come into to play, but suppose A = 5, B = 4, C = 3, D = 2, and E = 1. This gives us ((5 + 4) / 3) * ((2 - 5) + 1) or -6.
这是我需要帮助的地方.我进行了一些研究,发现2的称赞是一种解决方案,但是我不确定将其实现到我的代码中.
this is where I need help. I've done some research, and have found 2's compliment to be a solution, but I'm not sure to implement it into my code.
如果有人可以帮助我,我将非常感激!
If someone could help me, I'd be very grateful!
INCLUDE Irvine32.inc
; ((A + B) / C) * ((D - A) + E)
.data
valA dword 1
valB dword 2
valC dword 3
valD dword 4
valE dword 5
.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
exit
main ENDP
*除法和乘法过程分别除法和乘法.
*Divide and Multiply Procedures divide and multiply respectively.
推荐答案
Irvines的 WriteInt
,它将参数EAX
作为带符号的数字进行处理.
Irvines's WriteDec
should be replaced by WriteInt
which handles the argument EAX
as signed number.
在CPU内部,负的"-2"和正的"4294967294"被转换为相同的值:0xFFFFFFFE. DIV
积极执行6/-2除法(6/4294967294)并获得结果0 = 0x00000000,且 IDIV
结果正确:-3 = 0xFFFFFFFD.
Inside the CPU, the negative "-2" and the positive "4294967294" are transformed to the same value: 0xFFFFFFFE. DIV
performs the division 6/-2 positively (6/4294967294) and gets the result 0 = 0x00000000, with IDIV
the result is correct: -3 = 0xFFFFFFFD.
MUL
and IMUL
differ in the high part of the result (EDX
). Since the high part is not needed in this case, it is not mandatory to use IMUL
.
ADD
和
There are no different versions of ADD
and SUB
for signed and unsigned numbers. This was the main reason for introducing the 2's complement coding. It's just a thing of interpretation: if the programmer decides that this should be a signed number, then it is a signed number. If he/she/it decides that this is an unsigned number, then it is an unsigned number. The CPU doesn't care about such things - the results will be always the same.
Here's an example with WriteInt
, IDIV
and IMUL
:
; ((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
执行.
A 2's complement calculation is needed to get the absolute value of the number. E.g. the representation of -2 has two parts: a sign ('-') and an absolute value ('2'). A simple way to get the absolute value is to look at the sign bit, the leftmost bit of the number, and to jump appropriate. The calculation itself is performed just by NEG
.
带有WriteDec
, IDIV
和这里是一种无需跳跃即可获取EAX绝对值的算法:
Here is an algorithm to get the absolute value of EAX without jump:
cdq
xor eax, edx
sub eax, edx
这篇关于程序集MASM处理负整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!