Blackscholes
Blackscholes

Reputation: 45

Understanding intel SUB instruction

I am currently trying to deepen my understanding of assembly code and I am stuck since weeks with a seemingly simple instruction :

sub al, BYTE PTR [ebp+4]

Assuming eax = 0x11223300 and BYTE PTR [ebp+4] = 0xaa what is the value of eax after the above instruction ?

From what I understand, al can only affect the last byte in eax (0x00 in this case) so the program tries to compute 0x00 - 0xaa. But the result being negative, I don't get if the result would simply be 0x00 or if numbers are automatically transformed to a negative number, in which case 0xaa can itself be considered as a negative value which would imply we are trying to compute 0x00 - (-0x2a) = 0x2a

I found in the SUB documentation that

The SUB instruction performs integer subtraction. It evaluates the result for both signed and unsigned integer operands and sets the OF and CF flags to indicate an overflow in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result.

But it only describe some behaviour of the flags and I can't figure out how to look for more about those in such a specific case.

Upvotes: 0

Views: 3641

Answers (2)

Martin Rosenau
Martin Rosenau

Reputation: 18521

From what I understand, al can only affect the last byte in eax ...

This is correct.

But the result being negative ...

Now it becomes complicated.

Just like most CPUs, x86 does not distinguish between unsigned integers and "twos-complement" signed integers.

This means that 0xaa may mean 170 or (-86) and it's the task of the programmer or the compiler to interpret the value (if 0xaameans 170 or -86).

This is possible if only the low bits of a calculation are considered. Example:

0 + 170   = 0x000000AA
0 + (-86) = 0xFFFFFFAA

or:

0 - 170   = 0xFFFFFF56
0 - (-86) = 0x00000056

In both results above, the low 8 bits are equal.

So for an instruction that will only modify the low 8 bits, it does not care if 0xaa means 170 or (-86).

The x86's SUB instruction would write the low 8 bits of the result to the register and "throw away" the upper 24 bits.

The CPU sets the 4 bits in the "flags" register to pass additional information about these 24 bits to the program.

if the result would simply be 0x00

Some CPUs support instructions that operate like this: The result of a subtraction is 0 if the "correct" result would be negative.

However, such CPUs typically have two different SUB instructions: One that calculates like the SUB instruction of the x86 and another instruction that will saturate the result to 0.

Upvotes: 3

prl
prl

Reputation: 12455

You can think of it in two different ways, and they both give the same result.

As unsigned, the result is computed mod 256. So 0x00 – 0xaa mod 0x100 = 0x56.

As signed, 0xaa represents –0x56. (Not –0x2a as in the question.) So, 0x00 – (–0x56) = 0x56.

Upvotes: 4

Related Questions