了解装配间隔检查
Posted
技术标签:
【中文标题】了解装配间隔检查【英文标题】:Understanding an assembly interval check 【发布时间】:2015-12-21 14:02:39 【问题描述】:leal -0x61(%edx), %eax
cmpl $0x19, %eax
ja ... ;jump if edx is not between 0x61-0x7a
根据描述上面的代码sn-p检查edx是否在0x61-0x7a之间。如果没有,则进行跳转。
据我了解ja
检查 ZF 和 CF 标志,如果它们为零,则 anf 跳转。
我认为我唯一理解的是第二行,它计算 edx-0x7a。如果edx
如何检查 edx 是否大于 0x61?不是一直重置第二行CF吗?
让我们忘记第二行。如果 edx > 0x61 CF 为零,则跳转。这与描述不符。
【问题讨论】:
这有点小技巧。需要注意的关键是,您通过从 EDX 中减去 0x61,有效地将范围结束检查的底部标准化为 0x00。这里的关键部分是 JA 基于 unsigned 比较。因此,您将归一化范围的顶端与 0x19 进行比较。如果 unsigned 比较(无符号很重要)高于 0x19,则 EDX 最初在 0x61 到 0x7a 之外。 您可能会问如果 EDX 最初低于 0x61 会发生什么。减法会使它们变为负数,但是无符号比较会将它们视为具有最高有效位集的非常大的整数。例如,如果 EDX 中有 0x60。 0x60-0x61=-1。 -1 = 0xFFFFFFFF。作为一个环绕到整数范围高端的无符号数。 【参考方案1】:ja
表示如果高于(无符号)而不是大于(有符号)则跳转。 Michael Petch 已经在 cmets 中回答了这个问题,但如果有用,我会稍微不同地处理它。
在 C 中,这是这样做的
if ( ((unsigned)edx - 0x61U) > 0x19 )
goto ...;
对有符号值使用无符号比较会免费为您提供>= 0
,因为负符号值会变成大的正无符号值,大于最大有符号值 (INT_MAX
),因此比较结果与一个高于阈值的有符号值。
减去0x61
(与LEA
)将范围从0x61-0x7a
转移到0-0x19
,允许单个无符号比较来检查两个边界。
2.:注意ja
上的评论是在讨论edx
的范围,而cmp
是在测试eax
(减法后)。
【讨论】:
以上是关于了解装配间隔检查的主要内容,如果未能解决你的问题,请参考以下文章