我需要什么
我要求写的部分程序是一个补充。问题是我们被要求定义 bytes 并将它们转换为单词(签名扩展名),然后才添加它们。
问题
添加有时无法提供所需的输出。例如,我使用以下内容:
data segment
first DB 183
second DB 94
data ends
code segment
start:
mov ax,data
mov ds,ax
mov AX, 0
mov AL, first
cbw
mov BX, AX
mov AX, 0
mov AL, second
cbw
add AX, BX
mov ax, 4c00h
int 21h
code ends
end start
94( 5E in hex )+ 183( B7 in hex )= 277( 115 in hex ),但由于第一次cbw
, AX = FFB7 而不是 B7 。但是,第二个数字仍然是 AX = 5E ,因此将 AX = 15 中的两个结果与 CF = 1 相加。
我发现this page about CBW表示“如果AL的符号位(第7位)设置为”,则此指令将AH设置为0FFh“,这是我的情况,因为 B7 二进制是 1011 0111 。
我错过了什么吗?我应该以某种方式解释进位标志吗?为什么我没有获得 115(hex)?
提前致谢。
答案 0 :(得分:2)
94(5E,十六进制)+ 183(B7,十六进制)= 277(115,十六进制),但由于第一个cbw,AX = FFB7而不是B7。但是,第二个数字仍然是预期的AX = 5E,因此将两个结果添加到AX = 15,CF = 1. ...为什么我没有获得115(十六进制)
结果取决于值是应该被视为有符号还是无符号。
对于signed,应使用低位字节的最高位填充高位字节。这可以通过MOVSX
指令(例如MOVSX AX,AL
)或CBW
来完成(CBW
仅在操作数位于AL
中时才有效。)
字符0xB7
符号扩展为单词等于-73
(0xFFB7
)。所以预期的结果是94 - 73 = 21 (0x15)
。
对于无符号,您应该清除高位字节。这可以通过MOVZX
指令(例如MOVZX AX,AL
)或XOR完成:将高位字节与其自身(例如XOR AH,AH
)完成。
字段0xB7
零扩展到一个字等于183
(0x00B7
)。所以预期的结果是94 + 183 = 277 (0x115)
。
答案 1 :(得分:0)
您可以使用零扩展移动cbw
而不是movzx AX, AL
。
使用AL
指令时,不需要将字节存储在movzx
寄存器中。最佳代码可以是:
mov AL, first
movzx AX, AL
mov BL, second
movzx BX, BL
add AX, BX
编辑感谢Jester建议通过利用在movzx
中使用内存变量的可能性来进一步优化代码:
movzx AX,byte ptr [first]
movzx BX,byte ptr [second]
add AX, BX