由于CBW指令,有时会加两个单词行为不端

时间:2013-10-26 17:36:29

标签: assembly x86 byte word tasm

我需要什么

我要求写的部分程序是一个补充。问题是我们被要求定义 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)

提前致谢。

2 个答案:

答案 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符号扩展为单词等于-730xFFB7)。所以预期的结果是94 - 73 = 21 (0x15)


对于无符号,您应该清除高位字节。这可以通过MOVZX指令(例如MOVZX AX,AL)或XOR完成:将高位字节与其自身(例如XOR AH,AH)完成。

字段0xB7零扩展到一个字等于1830x00B7)。所以预期的结果是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