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…

四年级计算机课程,信息技术(四年级)全部课程PPT课件.ppt

信息技术(四年级)全部课程PPT课件调整窗口的大小 最小化 最大化 关闭 水平的双向箭头可以调整窗口的宽度&#xff0c;让窗口变宽或变窄。 调整窗口的大小 最小化 最大化 关闭 倾斜的双向箭头可同时调整窗口的高和宽。 做一做 打开我的文档&#xff0c;对窗口进行最小化、最大化…

python等腰梯形_简单空实心图形打印|Python练习系列[3]

def shape_print(n): #实心等腰三角形 for y in range(n): for x in range(n-y-1):#先循环打印空格 形成一个倒直角三角形 range()中的值是形成的规律 print( ,end) for z in range(y*21):#再循环打印X 形成一个等腰三角形 range()中的值是形成的规律 print(X,end) print() pri…

adas记录仪app_路影行车记录仪app

路影行车记录仪app具有非常强大实用的行车视频记录功能&#xff0c;能够清晰的记录车主的行车过程&#xff0c;路影app可以通过手机对路影行车记录仪进行设置&#xff0c;预览、回放、下载图片/视频等操作&#xff0c;p还能保存各种视频文件&#xff0c;下载导航地图等。路影行…

连接硬盘计算机没显示,新买的移动硬盘在我的电脑中无法显示,但是右下角图标显示已经连接,? 爱问知识人...

USB不被电脑识别&#xff0c;如果是系统或系统自带的驱动的原因&#xff0c;一般经过重启就可恢复或开机按F8进入安全模式在退出&#xff0c;在进入正常模式(修复受损的注册表)。U盘插入电脑&#xff0c;电脑提示“无法识别的设备”故障诊断方法如下。第1步&#xff1a;如果U盘…

爬虫python软件准备_工具准备的差不多了,接下来就是python爬虫的封装了

python爬虫的方便大家都懂的。那么&#xff0c;既然常用&#xff0c;那么我们当然要封装啦。 那么我们可以先封装一个父类的爬虫 我自己的设计想法就是&#xff0c;首先&#xff0c;爬虫必须要有个字段来存储匹配的规则gainRule&#xff0c;然后有个字段存储需要取什么属性outA…

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

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

计算机图像隐藏信息,学术讲座:杨庆隆-台湾成功大学-基于纠错码的信息隐藏与秘密图像共享...

学术讲座讲座题目:基于纠错码的信息隐藏与秘密图像共享讲座时间&#xff1a;2017.10.27。上午9&#xff1a;30-11&#xff1a;00讲座地点&#xff1a;十教10106讲座讲者&#xff1a;杨庆隆教授讲者简历&#xff1a;杨庆隆&#xff0c;台湾东华大学教授&#xff0c;博士&#xf…

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

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

xutils找id空指针_xUtils更新到3.0后的基本使用规则

说实话&#xff0c;对于xUtils&#xff0c;是我最近才用到的开发框架(也是刚接触)&#xff0c;对于其功能不得不说&#xff0c;简化了很多的开发步骤&#xff0c;可以说是非常好的开发工具&#xff0c;但是其最近更新到3.0也没有解决加载自定义ImageView报错的问题。我总是喜欢…

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…

微信时代计算机教学,互联网+时代技工院校计算机教学方式研究

刘兆慧摘 要&#xff1a;互联网时代的到来让几乎每一个行业的生产经营方式发生巨大变革&#xff0c;教育行业也不可避免。本文就技工院校计算机在互联网时代背景下采取的教学方式进行研究。本次研究采取了实验法、观察法、比较法等研究方法。结果显示&#xff0c;在互联网环境下…

python编写add函数求和_为什么python不利用__iadd__来实现求和和链接运算符?

我刚做了一个有趣的测试&#xff1a;~$python3 # I also conducted this on python 2.7.6, with the same resultPython 3.4.0 (default, Apr 11 2014, 13:05:11)[GCC 4.8.2] on linuxType "help", "copyright", "credits" or "license&quo…

python count函数用法 comm_python3:MySQL 8.0学习笔记(第五部分:单表查询操作)

在讲解单表查询时&#xff0c;首先创建一个emp的员工表&#xff0c;表中字段包括&#xff1a;empno&#xff08;员工编号&#xff09;、ename&#xff08;员工姓名&#xff09;、job&#xff08;员工职位&#xff09;、mgr&#xff08;员工领导&#xff09;、hiredate&#xff…

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

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

mysql主库从库在同一台服务器_MySQL数据库的主从配置(多主对一从)

一、实验环境部署主服务器 192.168.18.42 端口3306 》 从服务器 192.168.18.44 端口 3306主服务器 192.168.18.43 端口3306 》 从服务器 192.168.18.44 端口 3307##数据库&#xff0c;已经安装mysql服务&#xff0c;安装部分略。从服务器上的多个mysql实例&#xff0c;请看另…

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

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

domino缺省注册服务器或无法访问,Domino服务器挂起时的现象

1。Domino 服务器挂起时的现象&#xff1a;2。Domino 服务器挂起时需要收集的数据&#xff1a;3。Domino 服务器需要在notes.ini中添加的参数&#xff1a;4。有关QNC/Nsd&#xff1a;5。设置Statrep.nsf 的方法&#xff1a;6。有关用Debug_Capture_Timeout1来收集信号灯的数据信…

latex 分页_latex 图片跨页显示问题???

latex 中一个页面有很多图片&#xff0c;超出一页就显示不出来了&#xff1a;请问怎么让后续图片显示在一个新页面中&#xff1f;图片显示代码如下每行显示三张&#xff1a;\begin{figure}\centering\includegraphics[width1.8 in]{images/Fig5_Sample11a.jpg}\quad\includegra…