了解装配间隔检查

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(减法后)。

【讨论】:

以上是关于了解装配间隔检查的主要内容,如果未能解决你的问题,请参考以下文章

检查一个列表的间隔是不是与另一个列表的间隔重叠

使用 SQL 条件检查时间间隔

检查两个日期间隔是不是相交

后台 iBeacon 检查间隔

检查时间间隔是不是在今天

编译时间间隔检查器