问题
Assume the following code:
mov eax, 0
sub eax, 2
xor edx, edx
idiv base
where base
equals to 8 (defined as const int base = 8
).
As a result, I expect to get 0 in eax
and 2 (or −2) in edx
. However, the result of the division is a big long number. Most likely, it is caused by overflow in eax
registry, when I subtract 2 from it. I think eax
is interpreted by idiv
operation as unsigned int
. How do I perform this division properly?
I code in Visual Studio 2013 on x64 system.
回答1:
The usual reason: edx
is supposed to be the "upper half" of a 64bit dividend. So if you have a negative number, edx
can not be zero (at least the sign bit must be set, otherwise it's just not negative), and if you had a 32bit signed number, you have to sign-extend it into edx:eax
.
Which is what the cdq
instruction does, so it's easy:
mov eax, -2
cdq
idiv base
回答2:
Most probably the issue is the following: After the subtraction the value in EAX will be -2 represented in two's complement: 0xFFFF FFFE If you want to represent -2 on 64 bit you should have: 0xFFFF FFFF FFFF FFFE Because you are setting EDX to be 0, you will have the value 0x0000 0000 FFFF FFFE = 65534 instead of -2
You will have to set EDX to be 0xFFFF FFFF in case of a negative number and to 0 in case of a positive number.
来源:https://stackoverflow.com/questions/27385132/divide-a-negative-with-a-positive