Question

What I need

Part of the program I am requested to write is an addition. The thing is that we are requested to define bytes and the convert them to words (signed extension) and only afterwards add them.

The problem

The addition sometimes does not give the desired output. For example, I am using the following:

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), but because of the first cbw, AX = FFB7 instead of B7. However, the second number remains AX = 5E as expected, so adding the two results in AX = 15 with CF = 1.

I found this page about CBW where it states that "This instruction will set AH to 0FFh if the sign bit (bit 7) of AL is set", which is my case, because B7 is 1011 0111 in binary.

Am I missing something? Should I interpret the carry flag in some way? Why am I not obtaining 115 (hex) ?

Thanks in advance.

Était-ce utile?

La solution

94 (5E in hex) + 183 (B7 in hex) = 277 (115 in hex), but because of the first cbw, AX = FFB7 instead of B7. However, the second number remains AX = 5E as expected, so adding the two results in AX = 15 with CF = 1. ... Why am I not obtaining 115 (hex)

The result depends on whether the values should be viewed as signed or unsigned.

For signed, you should fill the upper byte with the most significant bit of the lower byte. This can be done with the MOVSX instruction (e.g. MOVSX AX,AL) or with CBW (CBW only works if the operand is in AL).

The byte 0xB7 sign-extended to a word equals -73 (0xFFB7). So the expected result is 94 - 73 = 21 (0x15).


For unsigned, you should clear the upper byte. This can be done with the MOVZX instruction (e.g. MOVZX AX,AL) or by XOR:ing the upper byte with itself (e.g. XOR AH,AH).

The byte 0xB7 zero-extended to a word equals 183 (0x00B7). So the expected result is 94 + 183 = 277 (0x115).

Autres conseils

Instead of cbw you can use the zero-extended move movzx AX, AL.

You don't need to store the bytes in AL register when using movzx instruction. An optimal code could read:

mov AL, first
movzx AX, AL

mov BL, second
movzx BX, BL

add AX, BX

Edit Thanks to Jester for his suggestion to optimize the code further by exploiting the possibility of using memory variable in movzx:

movzx AX,byte ptr [first]
movzx BX,byte ptr [second]
add AX, BX
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top