Tung Nguyen
Tung Nguyen

Reputation: 149

How does SUB with immediate in x86 work?

I have this code:

mov al, 0
sub al, 240

240 is over the signed range of the 8 bit register al. I suppose SUB is performed as usual then? By that I mean something like:

mov al, 0
mov cl, 240
neg cl
add cl ; two complement
add al, cl

However, when I try this code on my computer, the result differs from the actual sub instruction by 1. How is that so?

Upvotes: 0

Views: 1067

Answers (1)

C_Elegans
C_Elegans

Reputation: 1133

I'm assuming by add cl ; two complement, you really meant add cl, 1?

The neg instruction does two's complement negation of the register already, so neg cl is equivalent to

not cl ; invert all bits
add cl, 1 ; correct for two's complement.

So you have an extra addition of 1 in your second example. So you either need to get rid of your extra addition, or change the neg to not.

Regarding your initial question, yes 240 is too large for a signed byte to hold, however since the operand sizes are the same, the assembler doesn't really care whether one is signed or not, so it just encodes it as 240. So not only are

sub al, 240
sub al, -16

equivalent, they are both encoded as the same instruction: 80 e9 f0.

Upvotes: 6

Related Questions