How to compare signed value and unsigned value in x86 assembly
I am having trouble finding a way to compare positive number and negative number in x86 assembly code.
For example: when I compare -1 and 1, I always get -1 as greater. I know this is because 2's complement format makes -1 greater than 1 in the base binary.
But can anyone provide an x86 assembly snippet for comparing positive to negative and getting it mathematically correct? (for example 1> -1)
Thank!
source to share
You are probably using one of the unsigned options:
cmp eax, ebx
jb lesser
There are equivalents for checking signed numbers against each other, for example:
cmp eax, ebx
jl lesser
This link gives a good run on the jump variations, including their signature and flags they check, partially copied here for themselves -containment:
Instruction Jump if ... Signed? Flags
----------- ----------- -------- -----
JO overflow OF=1
JNO not overflow OF=0
JS sign SF=1
JNS not sign SF=0
JE/JZ equal
zero ZF=1
JNE/JNZ not-equal
not-zero ZF=0
JB/JNAE/JC below
not-above-or-equal
carry unsigned CF=1
JNB/JAE/JNC not-below
above-or-equal
no-carry unsigned CF=0
JBE/JNA below-or-equal
not-above unsigned CF=1 or ZF=1
JA/JNBE above
not-below-or-equal unsigned CF=0 and ZF=0
JL/JNGE less
not-greater-or-equal signed SF<>OF
JGE/JNL greater-or-equal
not-less signed SF=OF
JLE/JNG less-or-equal
not-greater signed ZF=1 or SF<>OF
JG/JNLE greater
not-less-or-equal signed ZF=0 and SF=OF
JP/JPE parity
parity-even PF=1
JNP/JPO not-parity
parity-odd PF=0
JCXZ/JECXZ CX register is zero
ECX register is zero
source to share
You cannot directly compare two numbers that have different signs. Actually most programming languages ββhave this thread. C and C ++ specifically mention that in their documentation and in most cases it will generate a warning when you use a signed and unsigned integer in the same expression, which can then lead to an unknown sign.
The only way is to check first if the signed number is negative, if so then you know it is less. Then you can compare the two numbers as unsigned integers.
; is eax < ebx (eax signed, ebx unsigned)
cmp eax, $0
jl less
cmp eax, ebx
jc less
Side note: obviously it is possible to compare two signed numbers if their size is less than the maximum size supported by the processor. In this case, you increment the signed and unsigned bit appropriately, then you can compare as if both values ββwere signed.
Assuming you want to compare the two bytes al and bl, then you might have something like this:
movsx ax, al
xor bh, bh ; or movzx bx, bl
cmp ax, bx
jl less
(Note, I do not guarantee that jl is correct, it could be jle or jnl ...)
source to share