gpt4 book ai didi

处理负整数的汇编 MASM

转载 作者:行者123 更新时间:2023-12-04 04:34:59 25 4
gpt4 key购买 nike

我被指示用汇编编写一个程序,该程序将执行以下算术运算:

((A + B)/C) * ((D - A) + E)

当没有负值发挥作用时,我已经成功地做到了这一点,但假设 A = 5、B = 4、C = 3、D = 2 和 E = 1。这给了我们 ((5 + 4)/3 ) * ((2 - 5) + 1) 或 -6。

这就是我需要帮助的地方。我做了一些研究,发现 2 的赞美是一个解决方案,但我不确定将它实现到我的代码中。

如果有人能帮助我,我将不胜感激!

包括 Irvine32.inc
; ((A + B)/C) * ((D - A) + E)
.data
valA 双字 1
valB 双字 2
valC 双字 3
valD 双字 4
值双字 5

.code
主程序

mov ecx, valA
添加 ecx, valB
mov edx, valC
调用划分
mov ecx, eax
mov edx, valD
子edx, valA
添加 edx, valE
调用乘法

退出

主ENDP

*除法和乘法程序分别进行除法和乘法。

最佳答案

尔湾的 WriteDec 应替换为 WriteInt 处理参数 EAX作为签名号码。

在 CPU 内部,负数“-2”和正数“4294967294”被转换为相同的值:0xFFFFFFFE。 DIV 对 6/-2 进行正除法 (6/4294967294) 并得到结果 0 = 0x00000000, IDIV 结果是正确的:-3 = 0xFFFFFFFD。

MUL IMUL 结果的高部分不同 ( EDX )。由于在这种情况下不需要high部分,因此不强制使用 IMUL .

ADD 没有不同的版本和 SUB 对于有符号和无符号数字。这是引入 2 的补码编码的主要原因。这只是一个解释:如果程序员决定这应该是一个有符号数,那么它就是一个有符号数。如果他/她/它决定这是一个无符号数,那么它就是一个无符号数。 CPU 不关心这些事情——结果总是一样的。

这是 WriteInt 的示例, IDIV 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 执行.

示例与 WriteDec , IDIV 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

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

关于处理负整数的汇编 MASM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19886399/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com