我无法找到比较x86汇编代码中的正数和负数的方法。
例如:当我比较-1和1时,我总是得到-1更大。我知道这是因为2的补码格式使-1在底层二进制中大于1。
但是,任何人都可以提供一个x86程序集的片段来比较正数和负数,并在数学上正确吗? (例如,1> -1)
谢谢!
答案 0 :(得分:10)
你可能使用其中一个无符号变体,如:
cmp eax, ebx
jb lesser
对于相互检查已签名的数字有等价物,例如:
cmp eax, ebx
jl lesser
This link可以很好地了解跳跃变化,包括他们的签名和他们检查的标志,部分复制到这里以进行自我控制:
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
答案 1 :(得分:2)
您无法直接比较两个具有不同符号的数字。实际上大多数软件语言都有这种流程。 C和C ++特别提到在他们的文档中,并且在大多数情况下,当您在同一表达式中使用有符号和无符号整数时会产生警告,然后可能导致未知符号。
唯一的方法是首先检查签名的数字是否为负数,如果是,那么你就知道它更小了。然后,您可以将这两个数字作为无符号整数进行比较。
; is eax < ebx (eax signed, ebx unsigned)
cmp eax, $0
jl less
cmp eax, ebx
jc less
旁注:显然可以比较两个签名的数字,如果它们的大小小于处理器支持的最大大小。在这种情况下,你适当地扩展有符号和无符号的位,然后你可以比较两个值都被签名。
假设你想要比较两个字节al和bl,那么你可以这样:
movsx ax, al
xor bh, bh ; or movzx bx, bl
cmp ax, bx
jl less
(注意,我不保证jl是正确的,它可能是jle或jnl ......)