打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
[翻译]ARM汇编简介(六)条件执行指令 && 分支指令

 条件执行指令

在讨论CPSR寄存器时,我们已经简要地讨论了条件的话题。当特定条件满足时,借助条件指令, 通过跳转(分支)或执行某些特定指令来控制程序的流动方向。相关条件被描述为CPSR寄存器中的特定位的状态,这些位根据指令计算后的结果实时改变。比如,如果我们比较两个数并且他们相等,就将零标志位置位(Z=1),因为在系统底层发生了a-b=0。在这个例子里两个数是相等的,但如果第一个数字比第二个大,会得出大于结论。而相反的情况下得出小于结论。当然还有很多其他的条件,比如小于等于(LE),大于等于(GE)等等。


下表列出了可能的条件指令,他们的含义以及被检测的状态标志位




我们使用如下代码来实现条件相加指令:

代码中,第一个CMP比较指令执行后触发了N标志位的置位(2-3=-1),这表明r0的值比数字3要小。随后,由于LT条件满足, 即V != N(在CPSR里溢出标志位和负标志位不是同一个),所以执行了addlt指令。由于第二个cmp指令将N标志位清空(因为3-3=0,不需要置位N标志位),将零标志位置位(Z=0),现在V = 0且 N = 0,从而导致LT条件不成立,结果就是第二个addlt没有执行,r0也没改变,程序退出并返回结果3 。


Thumb模式下的条件执行

在指令集那节我们谈到了不同Thumb版本间的差异。只有在特定版本中(Thumb-2)才能执行条件执行指令。一些ARM处理器版本支持IT指令集,可以在Thumb模式下执行4条条件指令


Syntax: IT{x{y{z}}}cond    语法结构:IT{x{y{z}}}cond(译者注:xyz指IT后最多再跟三个大写字母,大写字母可以是T,可以是E,T就是then,E就是else)

cond规定了执行IT语句块里的第一条指令需要满足的条件

x规定了执行的IT语句块中第二条指令需要满足的条件

y规定了执行IT语句块里的第三条指令需要满足的条件

z规定了执行IT语句块里的第四条指令需要满足的条件


IT指令集的结构是:“IF-Then-(Else)”,它的语法结构由两个字母构成:

IT代表If-Then(下一条指令是条件指令)

ITT代表If-Then-Then(接下来的两条指令是条件指令)

ITE代表If-Then-Else(接下来的两条指令是条件指令)

ITTE代表If-Then-Then-Else(接下来的三条指令是条件指令)

ITTEE代表If-Then-Then-Else-Else(接下来的四条指令是条件指令)


IT语句块内的每个指令必须指定一个条件后缀,该条件后缀那么相同要么在逻辑上相反。这意味着,如果使用了ITE,第一和第二指令(If-Then)必须具有相同的条件后缀,而第三条指令(else语句)必须和前面两条语句逻辑相反。以下是ARM参考手册中的一些例子,说明了这一逻辑:

Wrong syntax:错误的语法:

以下总结了条件指令和逻辑相反的指令:



用下面的示例代码尝试一下:

. code 32

这段示例代码以ARM状态开始。第一条指令将PC里的地址值加1后传送给r3,接着跳转到分支地址R3。这样做会导致切换到Thumb状态,因为LSB(最低有效位)是1,因此不是4个字节。使用bx指令(分支+切换)达成这个目标,分支指令执行完成后,T(Thumb)标志位被置位,我们现在处于Thumb模式。


. code 16

Thumb模式下首先用R0和立即数10比较。这会将N标志位置位(0-10=-10)。接着我们使用了一个If-Then-Else语句块。这个块会跳过ADDEQ因为Z(零)标志位没有被置位,由于结果等于10,是NE的(not equal不等于0的),接着会执行ADDNE指令。


在GBD中单步步过这段指令会把结果搞乱,因为在ITE语句块中两条语句都执行了。但不设置断点运行代码,并且单步步过每条指令会产生正确的结果:R1=3。


分支

分支指令(aka跳转)允许我们跳转到另一个代码段运行。当我们需要跳过(或者重复)执行代码段或者跳向特定功能的函数时就显得尤为有用。这方面最好的范例就是IFs和循环。我们先看看IF是什么情况。

上述代码只是简单检查了一些哪个变量初始化的值更大,而且将大数作为返回值。它的类C语言伪代码应该想这样的:

现在我们可以用条件分支指令和非条件分支指令来创建一个循环了。

类C语言伪代码如下:


B / BX / BLX

有三类分支指令。他们分别是:

1.分支指令(B)

a)简单地跳向一个函数

2.分支连接指令(BL)

a) 将(PC+4)保存到LR中并跳转到函数

3.BX指令:分支切换指令和BLX(分支连接切换指令)

a) 与B/BL+交换指令集相同(ARM <-> Thumb)

b) 需要用寄存器作为第一操作数:BX/BLX+具体的寄存器

BX/BLX用来从ARM指令集切换到Thumb指令集

这里的诀窍是获取实际的PC当前值,将其增加1,将结果存储到寄存器中,并将分支(+交换)存储到该寄存器。我们看到,加法(add r2, pc, #1)将简单地获取有效的PC地址(当前PC寄存器的值+ 8等于 0x805C),并加1(0x805c+1=0x805d)。然后,如果我们分支指令后面的地址的最低有效位(LSB)为1(这里就是这种情况,因为0x805D=10000000 01011101),意味着地址不是4字节对齐的,则发生状态转换。分支到这样的地址不会引起任何不对中问题。这就是代码在GDB(GEF扩展)的样子:


请注意,上面的GIF是使用较旧版本的GEF创建的,因此很可能看到稍微不同的UI和不同的偏移量。然而,逻辑是相同的。


条件分支指令 

分支还可以有条件地执行,如果满足特定条件,则分支到某函数。让我们来看一个非常简单的使用条件分支指令BEQ的例子。如果寄存器等于一个指定值,那么这段汇编代码除了把值给到寄存器并分支到另一个函数之外,没有什么特别有趣的地方。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ARM中的条件执行指令 (IT指令)
arm 跳转指令
ARM处理器体系架构详细说明
安卓逆向:重温Thumb汇编指令的细节
ARM微处理器的指令系统
【2011.03.21】ARM中断处理流程 & ARM中断处理分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服