Reputation: 45
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
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 0xaa
means 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
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