x86汇编中的符号冲突:movsx然后是未签名的比较/分支? [英] Conflicting signs in x86 assembly: movsx then unsigned compare/branch?

查看:87
本文介绍了x86汇编中的符号冲突:movsx然后是未签名的比较/分支?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对以下代码段感到困惑:

I am confused in the following snippet:

movsx   ecx, [ebp+var_8] ; signed move
cmp     ecx, [ebp+arg_0]
jnb     short loc_401027 ; unsigned jump

这似乎是矛盾的.Var_8似乎是在对其进行符号扩展的帐户上签名的.但是,jnb表示var_8没有在帐户上签名,这是未签名的比较.

This seems to conflict. Var_8 appears to be signed on the account of it getting sign-extended. Yet, jnb implies var_8 is not signed on the account it is an unsigned comparsion.

那么var_8是带符号的还是无符号的?那arg_0呢?

So, is var_8 signed or unsigned? And what about arg_0?

推荐答案

正如Jester所说,无符号比较可用于对有符号数进行范围检查.例如,一个通用的C表达式检查索引是否在0到某个限制之间:

As noted by Jester, unsigned comparison can be used to do range checks for signed numbers. For example, a common C expression that checks whether an index is between 0 and some limit:

short idx = ...;
int limit = ...; // actually, it's called "arg_0" - is it a function's argument?
if (idx >= 0 && idx < limit)
{
    // do stuff
}

在这里, idx 在符号扩展后是一个有符号的32位数字( int ).这个想法是,当将它与 limit 进行比较时,就好像它是未签名的一样,它会一次执行两个比较.

Here idx, after sign-extension, is a signed 32-bit number (int). The idea is, when comparing it with limit as if it were unsigned, it does both comparisons at once.

  1. 如果 idx 为正,则已签名"或未签名"无关紧要,因此未签名比较会给出正确的答案.
  2. 如果 idx 为负数,则将其解释为无符号数字将产生非常大的数字(大于2 31 -1),因此在这种情况下为无符号比较也可以给出正确的答案.
  1. If idx is positive, then "signed" or "unsigned" doesn't matter, so unsigned comparison gives the correct answer.
  2. If idx is negative, then interpreting it as an unsigned number will yield a very big number (greater than 231-1), so in this case, unsigned comparison also gives the correct answer.

因此,一个无符号比较将执行两个有符号比较的工作.仅当 limit 已签名且为非负数时,此方法才有效.如果编译器可以证明它是非负数,它将生成这样的优化代码.

So one unsigned comparison does the work of two signed comparisons. This only works when limit is signed and non-negative. If the compiler can prove it's non-negative, it will generate such optimized code.

另一种可能性是,如果初始C代码有错误,并且将带符号的代码与无符号的代码进行比较.C的一个令人惊讶的功能是,当将有符号变量与无符号变量进行比较时,其效果就是无符号比较.

Another possibility is if the initial C code is buggy and it compares signed with unsigned. A somewhat surprising feature of C is that when a signed variable is compared with unsigned, the effect is unsigned comparison.

short x = ...;
unsigned y = ...;

// Buggy code!
if (x < y) // has surprising behavior for e.g. x = -1
{
    // do stuff
}

if (x < (int)y) // better; still buggy if the casting could overflow
{
    // do stuff
}

这篇关于x86汇编中的符号冲突:movsx然后是未签名的比较/分支?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆