arm b bl 地址无关码_ARM汇编语言入门(六)

9e9f4ed9abe18e02efee90bb8e0fdf97.png

Part 6:条件状态和分支

在探讨CPSR时我们已经接触了条件状态。我们通过跳转(分支)或者一些只有满足特定条件才执行的指令来控制程序在运行时的执行流。通过CPSR寄存器中的特定bit位来表示条件状态。这些位根据指令每次执行的结果而不断变化。例如,比较运算时如果两个数相等,那么就置CPSR中的Zero位(Z=1),实际上是因为:a - b = 0,这种情况下就是相等状态。如果第一个数大,那么就是大于状态。如果第二个数大,就是小于状态。除此之外,还有小于等于大于等于等等。

下面的表格列出了可用的条件状态码,描述和标志位:

1f7ba2ec654e592f3435f610cc698733.png

在下面代码片段中看一下执行条件加法时的实际用法L:

.global main
​
main:mov     r0, #2     /* 初始化变量 */cmp     r0, #3     /* 将R0中的值与3比较,负数位置1 */addlt   r0, r0, #1 /* 如果上一条比较结果是小于(查看CPSR),则将R0加1 */cmp     r0, #3     /* 将R0中的值再与3比较, 零位置1,同时负数位重置为0 */addlt   r0, r0, #1 /* 如果上一条比较结果是小于(查看CPSR),则将R0加1 */bx      lr

第一条cmp指令结果导致CPSR中的负数位置1(2- 3 = -1)意思是R0小于R3。因为满足小于条件(CPSR中的溢出位不等于负数位V != N)所以接下来的ADDLT指令执行。在执行下一条cmp指令时,R0 = 3。所以清除负数位(3 - 3 = 0,负数位清零),零位置位(Z = 1)。现在溢出位是0,负数位是0,不满足小于条件。所以最后一条ADDLT指令不执行,R0值保持3不变。

Thumb模式下的条件执行

我们在介绍指令集的章节讨论了Thumb状态下的不同。具体而言是Thumb-2版本支持条件执行。某些 ARM 处理器版本支持"IT"指令,允许在 Thumb 状态下支持多达4个条件执行指令。参考:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABIJDIC.html

语法:IT{x{y{z}}} cond

  • cond 指定 IT 块的第一个指令的条件。
  • x 指定 IT 块中第二个指令的条件开关。
  • y 指定 IT 块中第三个指令的条件开关。
  • z 指定 IT 块中第四个指令的条件开关。

其实IT指令的结构就是“IF-Then-(Else)”,语法都是由字母“T”和“E”构成:

  • IT:If-Then(下一条指令是条件的);
  • ITT:If-Then-Then(后两条指令是条件的);
  • ITE:If-Then-Else(后两条指令是条件的);
  • ITTE:If-Then-Then-Else(后三条指令是条件的);
  • ITTEE:If-Then-Then-Else-Else(后四条指令是条件的);

IT块中的每条指令必须指定相同或逻辑相反的条件后缀。意思是,如果使用ITE,那么前两个指令必须有相同的后缀,而第三个必须是逻辑相反的后缀。下面是 ARM 参考手册中的一些示例,说明了这些逻辑:

ITTE   NE           ; 接下来的3条指令都是有条件的。
ANDNE  R0, R0, R1   ; ANDNE不更新条件标志。
ADDSNE R2, R2, #1   ; ADDSNE更新条件标志。
MOVEQ  R2, R3       ; 有条件的移动
​
ITE    GT           ; 接下来的2条指令都是有条件的。
ADDGT  R1, R0, #55  ; 条件满足大于时进行相加。
ADDLE  R1, R0, #48  ; 条件不满足大于时进行相加。
​
ITTEE  EQ           ; 接下来的4条指令都是有条件的。
MOVEQ  R0, R1       ; 有条件的MOV
ADDEQ  R2, R2, #10  ; 有条件的ADD
ANDNE  R3, R3, #1   ; 有条件的AND
BNE.W  dloop        ; 分支指令只能在IT块的最后一个指令中使用。

错误示例:

IT     NE           ; 下一条指令是条件的。     
ADD    R0, R0, R1   ; 语法错误,不是有条件的指令。

下面是条件代码和相反代码:

2a976a222c55c34a0ebe5b6eccc3f3d0.png

现在使用以下代码来测试:

.syntax unified    @ 非常重要!
.text
.global _start
​
_start:.code 32add r3, pc, #1   @ PC的值加1并存储到R3。bx r3            @ 跳转到R3中的地址处,并切换运行模式 ->切换到Thumb模式,因为R3最低有效位(LSB) = 1。
​.code 16         @ Thumb模式cmp r0, #10      ite eq           @ 如果R0等于10...addeq r1, #2     @ ... 那么 R1 = R1 + 2addne r1, #3     @ ... 否则 R1 = R1 + 3bkpt

.code 32

示例中的代码开始在ARM模式下,第一条指令将PC中的地址值加1并存储到R3,然后bx指令跳转到R3中的地址位置,并且模式切换成Thumb模式,因为R3中的值最低有效位为1(0不切换)。为此使用bx(分支+交换)非常重要。

.code 16

Thumb模式下,首先比较R010,结果将负数位N置位(0 - 10 = -10)。之后使用If-Then-Else块,因为零位Z(Zero)没有被置位所以ADDEQ指令被跳过,然后因为结果不相等所以执行ADDNE指令。

GDB 中单步执行此代码会干扰结果,因为你要在 ITE 块中执行这两个指令。 但是,在 GDB 中运行代码而不设置断点并单步执行每个指令将生成正确的结果设置 R1 = 3。

分支

分支(跳转)允许我们跳转到另一个代码段。当你需要跳过(或者重复)某块代码或者跳转到指定的函数的时候,分支很有用。此类情形中最佳的示例是IF和循环。先来看看IF案例。

.global main
​
main:mov     r1, #2     /* 设置初始变量a */mov     r2, #3     /* 设置初始变量b */cmp     r1, r2     /* 比较两个变量值看哪个更大 */blt     r1_lower   /* 因为R2更大(N==1),跳转到r1_lower */mov     r0, r1     /* 如果没有跳转, 例如R1的值更大(或者相等),则将R1的值存储到R0 */b       end        /* 结束 */
r1_lower:mov r0, r2         /* R1小于R2时跳转到此处, 将R2的值存储到R0 */b end              /* 结束 */
end:bx lr              /* THE END */

上面代码是比较两个初始值并返回最大值,C语言伪代码:

int main() {int max = 0;int a = 2;int b = 3;if(a < b) {max = b;}else {max = a;}return max;
}

现在再看一下怎么使用条件分支实现循环:

.global main
​
main:mov     r0, #0     /* 设置初始变量a */
loop:cmp     r0, #4     /* 比较a==4 */beq     end        /* 如果a==4,结束 */add     r0, r0, #1 /* 否则将R0中的值递增1 */b loop             /* 跳转到loop开始位置 */
end:bx lr              /* THE END */

C语言伪代码:

int main() {int a = 0;while(a < 4) {a= a+1;}return a;
}

B、BX、BLX指令

有三种类型的分支指令:

  • 普通分支(B)
    • 简单的跳转到一个函数。
  • 带链接的跳转(BL)
    • 将PC+4的值保存到LR寄存器,然后跳转。
  • 带状态切换的跳转(BX)和带状态切换及链接的跳转(BLX)
    • 与B和BL一致,只是添加了工作状态的切换(ARM模式-Thumb模式)。
    • 需要寄存器作为第一个操作数。

BX、BLX用来切换ARM模式到Thumb模式。

.text
.global _start
​
_start:.code 32         @ ARM modeadd r2, pc, #1   @ put PC+1 into R2bx r2            @ branch + exchange to R2
​.code 16          @ Thumb modemov r0, #1

这里的技巧是获得当前PC的值,加1然后保存到一个寄存器,然后跳转(并且切换状态模式)到这个寄存器内的地址。可以看到加指令(add r2, pc, #1)获取到有效的PC地址值(当前PC内的值+8=0x805C)然后加1(0x805C + 1 = 0x805D)。接下来,我们跳转的地址( 0x805D = 10000000 01011101)最低有效位为1,那么意味着地址不是4字节(32bit)对齐的。跳转到这样的地址不会导致非对齐问题。在GDB中运行的样子(含GEF):

cf64e73cb1a768fd7d4a48080e5b1679.gif

注意上面的gif图片是在低版本的GEF下创建的,所以你的显示界面可能不一样,但是逻辑是一样的。

条件分支

分支也可以有条件地执行,用于在满足特定条件时跳转到函数。我们看一个使用BEQ应用条件分支的例子,这是一段没太有用的汇编代码,只不过是在寄存器等于特定值时将一个值移动到寄存器并跳转到另一个函数的过程。

514350a8c449d3469883f96e1c0b7b4e.png
.text
.global _start
​
_start:mov r0, #2mov r1, #2add r0, r0, r1cmp r0, #4beq func1add r1, #5b func2
func1:mov r1, r0bx  lr
func2:mov r0, r1bx  lr

<end>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bcp out 带列名导出_从零开始学习 MySQL 系列索引、视图、导入和导出

阅读本文大概需要 8 分钟前言上篇文章我们学习了数据库和数据表操作语句&#xff0c;今天我们学习下数据库索引&#xff0c;视图&#xff0c;导入和导出的知识。作为基础篇&#xff0c;不会涉及到关于索引和视图的高级应用和核心概念&#xff0c;但是基本操作大家会了解&#x…

axure 输入框默认灰色字_Axure如何应对意外关闭

在使用Axure的时候&#xff0c;相信很多朋友都遇到过这样的情况&#xff1a;axure提交的东西都不见了。内容做到一半或者已经快要完成时&#xff0c;软件意外关闭&#xff0c;导致做的内容意外丢失。看着自己的劳动成果就这样浪费了&#xff0c;这种情况真的令人心疼。如果遇到…

matlaba绘制gps星空图_网络图横道图绘制软件 5.0免锁版告别纯手工绘制,修改工作量大!...

按图片加小编微信今日资料会员专属资料链接链接&#xff1a;https://pan.baidu.com/s/1AZY3cPeEv72GBRfESIwk_w提取码&#xff1a;88B8安装教程&#xff1a;1、下载压缩文件&#xff0c;解压后双击【网络计划V5.exe】&#xff0c;点击立即安装。2、没有替换补丁打开软件是这种情…

xp访问不了win10计算机,如何解决winxp访问win10共享打印机提示凭据不足

在win10的电脑上对着始按钮点鼠标右键&#xff0c;点击运行&#xff0c;或者直接“winR”输入gpedit.msc&#xff0c;点击确定&#xff0c;在本地策略组编辑器中依次点开——计算机配置——windows设置——安全设置——本地策略——安全选项&#xff0c;在右边的列表中找到“网…

centos7 关闭selinux_Devops之LDAP部署安装(centos7+openLDAP+PhpLDAPAdmin)

Devops之LDAP部署安装(centos7openLDAPPhpLDAPAdmin)由于公司部门的需求&#xff0c;需要搭建ldap来统一Devops的用户名和密码&#xff0c;具体的选择LDAP分析在上一篇里&#xff0c;这里主要记录一下部署centos7openLDAPPhpLDAPAdmin来实现Ldap服务&#xff0c;并使用phpldapa…

该计算机没有运行windows无线服务器,老司机示范win7系统诊断提示此计算机上没有运行的windows无线服务的恢复方法...

随着win7系统的普及&#xff0c;大家是否遇到过win7系统诊断提示此计算机上没有运行的windows无线服务的情况&#xff0c;近日就有朋友向我反映win7系统诊断提示此计算机上没有运行的windows无线服务的问题&#xff0c;那么我们应该如何处理win7系统诊断提示此计算机上没有运行…

golang int64转string_(一)Golang从入门到原地起飞

1、Golang 变量定义方法&#xff1a;1&#xff09;定义变量 变量名 类型 表达式var go string "hello" 2&#xff09;在函数内部&#xff0c;可以使用更简略的 : 方式声明并初始化变量。注意&#xff1a;短变量只能用于声明局部变量&#xff0c;不能用于全局变量的…

session传递参数_JWT与Session的比较

如今&#xff0c;越来越多的项目开始采用JWT作为认证授权机制&#xff0c;那么它和之前的Session究竟有什么区别呢&#xff1f;今天就让我们来了解一下。JWT是什么定义JSON Web Token(JWT)是一个开放标准(RFC 7519)&#xff0c;它定义了一种紧凑和自包含的方式&#xff0c;用于…

scp复制本地文件到远程服务器,scp 本地文件到远程服务器

linux中scp命令的使用linux远程拷贝文件命令:scp(scp:secure corp)(1)从本地拷贝文件到远程服务器scp/opt/script/test.pl root192.168.3.130:~/将本地/opt/scritp/文件夹下的test.pl脚本文件拷贝到远程服务器192.168.3.130的用户目录下...文章科技小能手2017-11-12758浏览量li…

keras 分布式_TensorFlow 2.0正式版官宣!深度集成Keras

新智元报道 来源&#xff1a;medium、GitHub编辑&#xff1a;小芹、大明【新智元导读】TensorFlow 2.0正式版终于发布了&#xff01;深度集成Keras&#xff0c;更简单、更易用&#xff0c;GPU训练性能提升。这是一个革命性的新版本&#xff0c;欢迎来到 TensorFlow 2.0&#x…

新天龙官网服务器更新消息,新天龙八部怀旧服太火,增开7组服务器不够用,还得继续扩容...

原标题&#xff1a;新天龙八部怀旧服太火&#xff0c;增开7组服务器不够用&#xff0c;还得继续扩容最近《新天龙八部》怀旧服上线的消息&#xff0c;相信各位都有耳闻&#xff0c;作为国产最经典的网游之一&#xff0c;新天龙开怀旧服自然吸引了无数老玩家回归。而且还有很多路…

大疆云台如何使用华为mate20pro_华为Mate30+大疆灵眸Osmo3,让你的照片和短视频称霸朋友圈...

自华为Mate30国内上市以后&#xff0c;短短几天刷爆朋友圈&#xff0c;尤其是Mate30pro现在更是一机难求。华为Mate30pro打造了全球首款4000万像素电影级拍摄手机&#xff0c;华为Mate30pro支持7680帧超慢速摄影&#xff0c;支持4K HDR拍摄&#xff0c;以及双OIS防抖。2019年8月…

c语言int转字符串_C语言零基础入门-指针-05

C语言零基础入门-指针-05本节要点&#xff1a;1&#xff0c;字符指针。2&#xff0c;字符串指针。3&#xff0c;指针的参数传递4&#xff0c;多重指针01. 字符指针这里的定义与前面的基本一样&#xff0c;所谓的字符指针就是这个指针指向的是一个字符型的变量。01.1 单个字符代…

圆平移后的方程变化_平移法解题

提要平面内把一个图形沿着一定的方向移动一定的距离得到另一个图形&#xff0c;这种变换称为平移变换。根据需要&#xff0c;平移的对象可以是线段&#xff0c;直线&#xff0c;角&#xff0c;圆&#xff0c;整个图形等。平移只改变图形的位置&#xff0c;不改变图形的形状和大…

有没有什么方法快速能找到导致软件崩溃的进程_崩溃!电脑突然黑屏无法启动...

Hello&#xff01;我是爽哥&#xff0c;欢迎你的到来&#xff0c;我会不定期推送关于电脑方面的实用教程及资讯&#xff0c;点击上方蓝色字体公众号名称“爽哥来搞机”关注我&#xff0c;实用干货全部拿走&#xff01;什么?!为什么我的电脑一直黑屏无法开机了&#xff0c;昨天…

服务器内存会显示ecc么,服务器内存ecc

服务器内存ecc 内容精选换一换设备实时状态查询是检测设备在运行过程中的状态信息。用户可任选以下指令之一查看设备实时状态查询命令的可用参数。ascend-dmi -i -hascend-dmi -i --help各参数解释如表1所示。以查看芯片的详细信息为例。ascend-dmi -i -dt若推理服务器返回如图…

可燃气体浓度多少合格_安燃无恙 | 可燃气体报警器的常见故障处理

说到报警器可能大家都不陌生&#xff0c;在商场、家居住宅、银行等场合都能够看到报警器的存在&#xff0c;而且随着科技的发展还出现了远红外报警器、烟感报警器等多功能报警器。它们不仅被应用在防盗方面还应用在消防领域用于火灾预警&#xff0c;但是今天说的这一种报警器算…

ajax荷马史诗,荷马史诗(8)

《奥德赛》(Odyssey)奥德修斯的希腊文原意是“麻烦”&#xff1a;他既带给别人麻烦&#xff0c;自己也遭遇麻烦《埃阿斯和卡珊德拉》(Ajax and Cassandra)《荷马史诗》里有两个埃阿斯&#xff0c;上图的埃阿斯又称小埃阿斯(Ajax theLesser)&#xff0c;特洛伊战争时罗克里斯(Lo…

nacos 本地测试_Nacos注册中心落地实践

前言公司在19年开始推进同城双活架构,未来规划是在南汇机房出现故障时能把所有读流量切到宝山机房,这样至少保证读请求是没问题的;我们的微服务使用的zookeeper来做服务发现, zk由于它的强一致性模型不适合多机房部署, 由于zk的服务发现模型是基于会话机制创建的临时节点, 就算…

python通讯录管理系统 tk_通讯录管理系统课程设计

按照惯例&#xff0c;一波课程设计走起~ 这次写的是通讯录管理系统&#xff0c;经过几番大修和N1次小修之后BUG已经很少了~先来看看期间遇到的哪些问题吧&#xff1a; Qusetion 1&#xff1a;针对手机号的排序问题&#xff08;即交换结构体&#xff09; 2&#xff1a;文件写入和…