Skip to main content

Signed Operations

NEG Instruction

NEG negates the sign of the number using two's compliment. It flips all the bits (0 becomes 1, 1 becomes 0) and add 1.

Example in 8 bits

mov al,3d
neg al

; 3 in binary is [ 0 0 0 0 | 0 0 1 1]
; neg 3 == [ 1 1 1 1 | 1 1 0 0] == 0xfd

MOVSX and MOVZX

In some cases we want to extend an 8-bit to a 16-bit number.

When we want to extend a positive number, we add leading 0s. So 3 == [ 0 0 0 0 0 0 1 1] becomes [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 ].

When we want to extend a negative number, we add leading 1s. So -3 == [ 1 1 1 1 1 1 0 1] becomes [ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1].

Because this is cumbersome, we have MOVSX and MOVZX which extend while moving.

To extend unsigned numbers, use MOVZX:

movzx eax,bl ; extends bl using leading zeroes and stores the result into eax.

To extend signed numbers, use MOVSX. If the leading bit is 1, MOVSX extends using leading zeroes. If the leading bit is 0, MOVSX extends using leading 1s.

CBW and CWDE

CBW - convert byte to word (word is 2-bytes). It is used to sign-extend al to ax. CWDE - convert word to double word. It is used to sign-extend ax to eax.

For example:

mov al,10001010b
cbw
; ax == 1111111110001010

cwde
; eax == 11111111111111111111111110001010

There are also CWD and CDQ specifically for the edx register.

CWD - convert word to double-word. It is used to sign-extend ax to dx:ax. CDQ - convert double-word to quadword (32-bit to 64-bit). It is used to sign-extend eax to edx:eax.

IMUL and IDIV

IMUL and IDIV are sign-aware multiplication and division instructions.

CDQ and IDIV are usually used together:

; program to divide eax by 3

mov esi,3
cdq
idiv esi