assembly - x86 程序集中的冲突符号:movsx 然后是无符号比较/分支?
问题描述
我对以下代码段感到困惑:
movsx ecx, [ebp+var_8] ; signed move
cmp ecx, [ebp+arg_0]
jnb short loc_401027 ; unsigned jump
这似乎有冲突。Var_8 似乎是在它得到符号扩展的帐户上签名的。然而, jnb 暗示 var_8 未在帐户上签名,它是未签名的比较。
那么,var_8 是有符号的还是无符号的?那么arg_0呢?
解决方案
正如 Jester 所指出的,无符号比较可用于对有符号数进行范围检查。例如,检查索引是否介于 0 和某个限制之间的常见 C 表达式:
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
无符号进行比较时,它会同时进行两种比较。
- 如果
idx
为正,则“有符号”或“无符号”无关紧要,因此无符号比较给出正确答案。 - 如果
idx
为负数,则将其解释为无符号数将产生一个非常大的数(大于 2 31 -1),因此在这种情况下,无符号比较也给出了正确答案。
所以一个无符号比较完成了两个有符号比较的工作。这仅在limit
有符号且非负数时有效。如果编译器可以证明它是非负的,它将生成这样的优化代码。
另一种可能性是,如果最初的 C 代码有问题,并且比较有符号和无符号。C 的一个有点令人惊讶的特性是,当将有符号变量与无符号变量进行比较时,效果是无符号比较。
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
}
推荐阅读
- tableau-api - 如何切换 Tableau 数据源上的连接
- javascript - 如何在单击时呈现不同的组件?(组件应替换为最新的单击处理程序。)
- c++ - 试图在 C++ 中“模糊”矩阵;有缺陷的算法或代码?
- angular - 不使用 .expand() 的 rxjs 观察者分页模式?
- wordpress - 如何更改 Wordpress 默认字段的显示标签?
- javascript - Cognito 如何验证密码?
- javascript - Postman - 如何从 JSON 对象内的 JSON 数组中获取值
- gradle - 如何将要发布的工件与我的 Maven 存储库中的特定版本进行比较?
- java - Java:使用日期排列填充二维数组或嵌套列表,仅考虑优先级(而不是值)允许空值和重复值
- python - selenium.common.exceptions.ElementNotVisibleException:消息:尝试使用 Selenium Python 单击元素时出现元素不可交互错误