A buggy example code is in 3.8.4.1 Rounding Mode.
add ecx,7fffffffh ; If diff<0 then decrement integer
adc eax,0 ; INC EAX (add CARRY flag)
ret
add ecx, 7fffffffh ; If diff<0 then decrement integer
sbb eax, 0 ; DEC EAX (subtract CARRY flag)
ret
In 32-bit x86 ABI, EDX and EAX registers are used to represent 64-bit integers.
EDX used for upper 32-bit value, EAX used for lower 32-bit value.
For example, the value 0x1234567890 is EDX = 0x12, EAX = 0x34567890.
If carry or borrow occurred in EAX, it must be reflected in EDX.
But the above code forgets it.
Therefore subtracting 1 from 0x100000000(EDX = 1, EAX = 0) will be 0x1FFFFFFFF(EDX = 1, EAX = 0xFFFFFFFF).
Adding 1 to -1 (EDX = 0xFFFFFFFF, EAX = 0xFFFFFFFF) will be -4294967296 (EDX = 0xFFFFFFFF, EAX = 0).
_ftol2
of VC ++ refers to Intel code.
But VC++'s _ftol2
is fixed bug.