简体   繁体   English

如何在 x86 程序集中比较有符号值和无符号值

[英]How to compare a signed value and an unsigned value in x86 assembly

I am having trouble finding a way to compare a positive number and a negative number in x86 assembly code.我很难找到一种方法来比较 x86 汇编代码中的正数和负数。

For example: when I compare -1 and 1 I always get -1 as greater.例如:当我比较 -1 和 1 时,我总是得到 -1 更大。 I know that it's because 2's complement format makes the -1 bigger than 1 in underlying binary.我知道这是因为 2 的补码格式使基础二进制中的 -1 大于 1。

But can anyone provide a snippet of x86 assembly to compare positive number with a negative one and get it mathematically correct?但是任何人都可以提供一段 x86 程序集来比较正数和负数并在数学上正确吗? (eg 1 > -1) (例如 1 > -1)

You're probably using one of the unsigned variants like:可能正在使用其中一种无符号变体,例如:

cmp  eax, ebx
jb   lesser

There are equivalents for checking signed numbers against each other, such as:有等价物可以相互检查带符号的数字,例如:

cmp  eax, ebx
jl   lesser

This link gives a good run down on the jump variations, including their signed-ness and the flags they check, partially copied here for self-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

You can't directly compare two numbers that have different signs.您不能直接比较具有不同符号的两个数字。 Actually most software languages have that flow.实际上大多数软件语言都有这种流程。 C and C++ specifically mention that in their documentation and in most cases will generate a warning when you use a signed and an unsigned integer in the same expression which then can result in an unknown sign. C 和 C++ 在他们的文档中特别提到,当您在同一表达式中使用有符号和无符号整数时,在大多数情况下会生成警告,这可能会导致未知符号。

The only way is to first check whether the signed number is negative, if so then you know it is smaller.唯一的方法是首先检查有符号数是否为负数,如果是,那么你知道它更小。 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: it is obviously possible to compare two numbers signed if their size is less than the maximum size supported by the processor.旁注:如果两个数字的大小小于处理器支持的最大大小,则显然可以比较两个带符号的数字。 In that case you extend the bits of the signed and unsigned appropriately, then you can compare as if both values were signed.在这种情况下,您可以适当地扩展有符号和无符号的位,然后您可以像两个值都已签名一样进行比较。

Assuming you wanted to compare two bytes al and bl, then you could have something like this:假设你想比较两个字节 al 和 bl,那么你可以有这样的东西:

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 may be jle or jnl...) (注意,我不保证jl是正确的,可能是jle或者jnl...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM