armv8 汇编 绝对地址赋值_详解汇编语言B和LDR指令与相对跳转和绝对跳转的关系...

@[TOC]

为什么要有相对跳转和绝对跳转?

顺序执行:指令一条一条按照顺序往下执行,比如变量的定义和赋值都是按照顺序执行的。跳转执行:当指令执行到当前位置后跳转到其他位置执行。比如,在主函数中调用其他函数就是典型的跳转执行。其中跳转又分为绝对跳转和相对跳转。绝对跳转:直接跳转到一个固定的,实实在在的地址。相对跳转:相对于当前pc值的一个跳转,跳转到pc+offset的地址。

  我们清楚了上面几个概念,就知道了为什么要有相对跳转和绝对跳转。各种指令相互配合才能使得cpu有更高的处理效率。正是因为有了顺序和跳转指令,我们的cpu才可以处理各种复杂的计算。

在程序中只有相对跳转/绝对跳转是否可以?

  答案肯定是不可以的。我们以一个例子具体分析。指令编号 | 指令功能-------- | -----| -----指令1 | 顺序执行指令2 | 顺序执行指令3 |相对跳转到指令5指令4 | 顺序执行指令5 | 顺序执行指令6 | 绝对跳转到指令8指令7 | 顺序执行指令8 | 顺序执行

  假设程序被放在0x00000000位置开始执行,编译链接后的结果为:

指令地址 | 指令编号 | 指令功能 | 下条指令地址-------- | -----| -----| -----| -----0x00000000 | 顺序执行| 顺序执行| 当前地址+40x00000004 | 顺序执行| 顺序执行| 当前地址+40x00000008 |跳转到指令5|跳转到指令5|当前地址+80x0000000C | 顺序执行 | 顺序执行 | 当前地址+40x00000010 | 顺序执行 | 顺序执行 | 当前地址+40x00000014 | 跳转到指令8| 跳转到指令8| 0xC000001C0x00000018 | 顺序执行| 顺序执行|当前地址+40x0000001C | 顺序执行 | 顺序执行 | 当前地址+4

dcbd33dab7c39baad9518b7de6f3a5c6.png

  当这段程序被放在0xC000000空间时,开始执行指令1,然后采用相对寻址的方法就可以运行到指令6,在指令6执行时也可以使用绝对寻址的方法从0xC0000014正确跳转到指令8所在的0xC00001C位置,这段代码运行正常。

  当这段代码被放在0x00000000空间时,开始执行指令1,然后采用相对寻址的方法就可以运行到指令6,但在指令6执行时使用绝对寻址的方法从0x0000014跳转到了0xC000001C,但0xC000001C空间没有代码,这样程序就跑飞了。

  因此,当编译地址(加载地址)和运行地址相同时,绝对跳转和相对跳转都可以正确执行。比如,程序在NORFLASH存储时。但是,当编译地址(加载地址)和运行地址不相同时,相对跳转都就会出现问题。比如,代码存储在NANDFLASH,由于NANDFLASH并不能运行代码,所以需要重定位代码到内部的SRAM。关于NANDFLASH和NORFLASH可以看这篇文章S3C2440从NAND Flash启动和NOR FLASH启动的问题。

B(BL)和LDR指令具体怎么执行的?

  我们以下图中的这句跳转代码分析下指令具体的执行过程。

#ifndef CONFIG_SKIP_LOWLEVEL_INIT    bl    cpu_init_crit#endif

  上述代码对应的反汇编代码如下:

33f000ac:    eb000017     bl    33f00110 
33f00110 :33f00110:    e3a00000     mov    r0, #0    ; 0x033f00114:    ee070f17     mcr    15, 0, r0, cr7, cr7, {0}

  当指令执行到33f000ac时,对应的机器码为eb000017(1110 1011 0000 0000 0000 0000 0001 0111‬),其中[31,28]高四位为条件码,1110表示无条件执行。[25,27]位保留区域,24位表示是否带有返回值,1表示带有返回值,也就是BL指令。[23,0]为指令的操作数,0000 0000 0000 0000 0001 0111。按照如下计算方式:

  1、将指令中24位带符号的补码立即数扩展为32位(扩展其符号位)原数变成 0000 0000 0000 0000 0000 0000 0001 0111。

  2、将此数左移两位0000 0000 0000 0000 0000 0010 1000 0000 变成 0000 0000 0000 0000 0000 0000 0101 1100 = 0x0000005c

   3、将得到的值加到PC寄存器中得到目标地址,由于ARM为3级流水线,此时的 pc = 33f000ac+8 = 33F000B4,pc = 33F000B4 + 0x0000005c = 33F00110‬与图中的cpu_init_crit的地址相等。

   在算的过程中我们使用的始终是PC的值,假设程序在 0 地址处执行,那么计算方法一样,pc 的值变了计算出来的结果也随之改变。所以 BL 的跳转时与位置无关的。

  下图为B(BL)指令的格式50a8b4f20b2ca2f8a89110b233d8fa28.png  28~31bts(cond)是条件码,就是表明这条语句里是否有大于、等于、非零等的条件判断,这4bts共有16种状态,分别为:f8022b4383134c61e0f93b7c4af73335.png  下图为LDR指令的格式ab826a70cb5a8474e2e43e87177c20d3.pnga836bf4136c04ee1563c39990b86208d.png  我们以下图中的第一句话作为例子分析下

ldr pc,=call_board_init_f

对应的反汇编代码如下:

33f000d0:    e59ff324     ldr    pc, [pc, #804]    ; 33f003fc 
33f003fc:    33f000d4     .word    0x33f000d4........33f000d4 :33f000d4:    e3a00000     mov    r0, #0    ; 0x0

   ldr pc, [pc, #804]这条指令为伪指令,编译的时候会将call_board_init_f的链接地址存入一个固定的地址(链接时确定的),对于本条指令这个地址就是33f000d4 。上面的反汇编出来的 ldr pc,=call_board_init_f就变成了ldr pc, [pc, #804],由于ARM使用了流水线的原因,所以在执行 ldr pc. [ pc, #4 ]的时候 pc 不在这句代码这里了,而是跑到了 pc+8的地方,这句代码相当于 pc = *(pc+804+8)=33f000d0+32C=33f003fc ,所以会跳转到33f003fc 地址取33f000d4 ,而33f000d4 是存在代码段中的一个常量,并不是计算出来的,不会随程序的位置而改变,所以无论代码和pc怎么变 *(pc+804) 的值时不会变的。

  这样,绝对跳转中的固定地址就很好理解了,要跳转地址的值在链接时就已经确定了,存在了一块内存中。而相对跳转时,反汇编bl 33f00110中的33f00110是根据pc计算出来的,当pc改变时,结果也会改变,所以,称为相对跳转,与当前位置无关。

B(BL)和LDR跳转范围是如何规定的?

  下图为B(BL)指令的格式63bbfe939a04241bead54cb652d41e31.png  BL指令的[23,0]bits存放的是要跳转的相对地址,由于指令所在地址必须是4字节对齐的,因此跳转的地址最低bits必然是0,因此BL指令[23,0]bits保存的是省略这最低2bts的地址,如果补全了这2bits,BL指令就可以表示26bits的跳转地址。在这26bits中需要使用1bit表示向前跳还是向后跳,那么剩下的25bits就可以表示32 MBts的范围了,225=32M因此,B(BL)指令的跳转范围为-32MBytes~+32MBytes。

  下图为LDR指令的格式c1e059d04b28ca16d48049f686564e4a.png5385aa72fa230430a8119b13089b73f1.png  图中的LDR的跳转范围计算方式和B指令的类似,其中Rn和Address_mode共同构成第二个操作数的内存地址,由Address_mode的9种格式可以直到,Address_mode表示的就是偏移地址的范围大小,为212=4K。(不理解的可以对比下ldr pc, [pc, #804]和Address_mode的九种格式,很明显可以看出Address_mode就是当前地址的偏移范围)

  大家的鼓励是我继续创作的动力,如果觉得写的不错,欢迎关注,点赞,收藏,转发,谢谢!

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

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

相关文章

BZOJ 4034: [HAOI2015]T2 树链剖分

4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个 操作,分为三种:操作 1 :把某个节点 x 的点权增加 a 。操作 2 :把某个节点 x 为根的子树中所有点的点权都增加…

mysql把游标数据存入表中_mysql数据库怎么使用游标

存储过程完整代码.CREATE DEFINERrootlocalhost PROCEDURE cj_zongfen()BEGINDECLARE yw INT;#语文成绩DECLARE sx INT;#数学成绩DECLARE yy INT;#英语成绩DECLARE d INT;DECLARE nf BOOLEAN DEFAULT TRUE;DECLARE zongfen_cursor CURSOR FOR SELECT yuwen,shuxue,yingyu,cid …

yum安装ruby_centos 6.5 ruby环境安装

redis3.0以上支持集群,自带集群管理工具redis-trib.rb;在搭建集群前,安装ruby环境安装开发工具1、命令:yum groupinstall "Development tools"清理已安装过的2、命令:yum erase ruby ruby-libs ruby-mode ru…

mongodb3.0 性能測试报告 一

mongodb3.0 性能測试报告 一 mongodb3.0 性能測试报告 二 mongodb3.0 性能測试报告 三測试环境: 服务器:X86 pcserver 共6台 cpu: 单颗8核 内存:64G 磁盘: raid 10 操作系统 :centos 6.5 mongo…

db2 某个字段排序_MySQL、Oracle、DB2等数据库常规排序、自定义排序和按中文拼音字母排序...

MySQL常规排序、自定义排序和按中文拼音字母排序,在实际的SQL编写时,我们有时候需要对条件集合进行排序。下面给出3中比较常用的排序方式,mark一下1.常规排序ASC DESCASC 正序DESC倒叙-- 此处不用多讲2.自定义排序自定义排序是根据自己想要的…

QML官方系列教程——QML Applications

附网址:http://qt-project.org/doc/qt-5/qmlapplications.html假设你对Qt的官方demo感兴趣,能够參考本博客的另一个系列Qt5官方demo解析集每一个绿色字体均是一篇博文连接。请收藏本文,本文会持续更新 。QML Applications —— QML应用程序QM…

51单片机基本刷屏测试实验_基于单片机的发动机振动速度、位移和加速度测量方法...

Single-chip microcomputer-based measuring of engine vibration  speed、displacement and accelerationAbstract: This paper presents a measuring method of engine vibration speed、displacement and acceleration。At first the signal from vibration senor of engin…

python正则表达式group用法_【Python】正则表达式用法

导读:正则在各语言中的使用是有差异的,本文以 Python 3 为基础。本文主要讲述的是正则的语法,对于 re 模块不做过多描述,只会对一些特殊地方做提示。很多人觉得正则很难,在我看来,这些人一定是没有用心。其…

HTTP 错误 404.3 – Not Found 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。...

今天,在vs2013中新建了一个placard.json文件,当我用jq读取它的时候,去提示404,直接在浏览器访问这个文件,提示: HTTP 错误 404.3 – Not Found 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本&…

python操作redis集群_python操作redis集群

strictRedis对象方法用于连接redis指定主机地址,port与服务器连接,默认db是0,redis默认数据库有16个,在配置文件中指定database 16上代码1、对redis的单实例进行连接操作根据不同的实例方法,与redis的命令对应python3&…

ArcGIS将CAD等高线转换为TIN/DEM数据

1.CAD图层分离 CAD快捷命令QSELECT(快速选择) 选择DGX,GCD图层,复制到新的CAD文件中 2.在ArcGIS中,将dwg文件转化为可编辑的要素类文件(shapefiles) 分析工具-提取分析-筛选 3.高程数据修正 鼠标右键生…

这周工作

这周在课上做了简单的小程序,做我感觉不是很好,好多东西不会,觉得上学年学的好多知识都没有搞懂,课下在看书期间,还是有好多看不懂。我在深思我我就是个打酱油的。转载于:https://www.cnblogs.com/wulaoliu/p/5277037.…

字节跳动专家会_字节跳动招聘直播策略运营专家/经理/海外财务AR BP,ACCA优先...

字节跳动是把人工智能技术大规模应用于信息分发的公司,短短7年,从最初的一个“今日头条”,已经发展为拥有“抖音”、“西瓜视频”、“火山小视频”、“FaceU”等十几款产品的公司。每天,都有6亿用户通过字节跳动的产品看见更大的世…

矩形河道中心排放污染物浓度点源二维移流扩散MATLAB解析解计算

某非可降解物质在20℃水体中从河道中心排放,速度与水流流速方向相同,排污口为时间连续点源。河道为矩形河道,长度16.0m,宽度3.0m,水深2.0m,水流流速2.0m/s。单位时间投放的污染物强度为30mg/L。假设污染物排…

elementui树状菜单tree_vue.js+element-ui做出菜单树形结构

这次给大家带来vue.jselement-ui做出菜单树形结构,vue.jselement-ui做出菜单树形结构的注意事项有哪些,下面就是实战案例,一起来看一下。由于业务需要,要求实现树形菜单,且菜单数据由后台返回,在网上找了几…

ArcGIS如何将经纬度坐标显示转化为xy坐标显示

GIS中经纬度坐标显示如图: 视图-数据框属性-常规-显示(米) 点击确定,然后坐标显示就转换为xy坐标了 注意,以上设置只是设置了当前文档的坐标系统,并不是数据的坐标系 举个例子:我将2160这条等高…

poj 2503 Trie树

典型的Trie树&#xff0c; 算是复习一下字符串吧&#xff0c; 就是输入有点恶心&#xff0c;代码如下&#xff1a; #include <cstdio> #include <cstring> #include <algorithm>using namespace std; const int maxn 500000100; struct Trie{bool isword;in…

尚硅谷k8s安装文档_Kubernetes(k8s)中文文档 从零开始k8s_Kubernetes中文社区

译者&#xff1a;王乐这部文档是面对想要学习Kubernetes集群的读者。如果你对入门指南已经可以满足你对这个列表上所列的需求&#xff0c;我们建议你继续阅读这个&#xff0c;因为他是根据前人积累经验所写的新手指南。当然如果除了学习入门指南知识外还希望学习IaaS&#xff0…

ArcGIS改变数据集或要素类的的坐标系(投影)

数据管理工具-投影和变换-投影-输入数据集或要素类-输出数据集或要素类-输出坐标系(选择合适的投影坐标系)

用python模拟评委打分_用vb 编写一个评委打分的程序1. 编写一个评委打分的程序,实现以下功能:a) 单击“评委给分”按钮时弹出InputBo...

共回答了20个问题采纳率&#xff1a;80%Dim a(10) As IntegerPrivate Sub Command1_Click()For i 1 To 10a(i) InputBox("请输入第" & i & "个分数")Text1.Text Text1.Text & Str(a(i))Next iEnd SubPrivate Sub Command2_Click()Max a(1)…