汇编指令-位置无关码(BL)与绝对位置码(LDR)(2)
位置无关码
即该段代码无论放在内存的哪个地址,都能正确运行。究其原因,是因为代码里没有使用绝对地址,都是相对地址。
位置相关码
即它的地址与代码处于的位置相关,是绝对地址
BL :带链接分支跳转指令,也是位置无关码(相对位置),用于调用函数用的。
B:分支跳转指令,指目标不能太远,一般用于同一个文件下的目标地址跳转。
LDR:通常都是作加载指令的,但是它也可以作伪指令,通常有两种不同的表示:
1)LDR pc, =MyHandleIRQ 表示将MyHandleIRQ地址放入pc寄存器中,相当于PC=MyHandleIRQ 。
1. LDR r0,=label //用于加载立即数或一个地址值到指定寄存器中
//如果label是立即数: LDR r0,=0X123 ;将0X123存入r0中
//如果name是个标识符: LDR r0,=label_1 ;将label_1所指向的地址值存入r0中
例如:
- LDR r0,[r1] //将R1中的值存到r0中
- LDR r1,[r2,#16] //将(r2+16)地址中的内容存到r1中
- LDR r1,[r2],#4 //将r2地址中的内容存到r1中,同时r2=r2+4
Reset:
ldr sp, = @ 设置栈指针,以下都是C函数,调用前需要设好栈
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
// bl是位置无关码,相当于:PCnew = PC + 偏移
// PCnew = (4+8) + 0x28 = 0x34 //ldr pc, =disable_watch_dog /* 这样写将出错 */ bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK
bl memsetup @ 设置存储控制器以使用SDRAM
bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
ldr pc, =on_sdram @ 跳到SDRAM中继续执行
on_sdram:
ldr sp, =0x34000000 @ 设置栈指针
ldr lr, =halt_loop @ 设置返回地址
ldr pc, =main @ 调用main函数
halt_loop:
b halt_loop
链接脚本如下,链接地址在0X30000000:
SECTIONS {
. = 0x30000000;
.text : { *(.text) }
.rodata ALIGN() : {*(.rodata)}
.data ALIGN() : { *(.data) }
.bss ALIGN() : { *(.bss) *(COMMON) }
}
反汇编如下:
<_start>:
: e3a0da01 mov sp, # ; 0x1000
: eb00000a bl <disable_watch_dog>
: eb00000d bl <clock_init>
3000000c: eb000026 bl 300000ac <memsetup>
: eb000040 bl <copy_steppingstone_to_sdram>
: e59ff00c ldr pc, [pc, #] ; <.text+0x28> <on_sdram>:
: e3a0d30d mov sp, # ; 0x34000000
3000001c: e59fe008 ldr lr, [pc, #] ; 3000002c <.text+0x2c>
: e59ff008 ldr pc, [pc, #] ; <.text+0x30> <halt_loop>:
: eafffffe b <halt_loop>
: andcc r0, r0, r8, lsl r0
3000002c: andcc r0, r0, r4, lsr #
: andcc r0, r0, r0, lsl # <disable_watch_dog>:
... ...
从反汇编中可以看出当执行ldr pc, =on_sdram 时的反汇编是 ldr pc, [pc, #12] ; 相当于pc=*(pc+12)=30000018,此时的*(pc+12)是指的pc+12地址所指的地址,所以无论pc怎么变都是指的30000018这个常量来执行on_sdram,属于绝对转移。
执行 bl disable_watch_dog 时,地址0X30000004跳转到0X30000034.这里的0X30000034是通过机器码算出来的,机器码格式如下图所示:

其中[31:28]位是条件码;[27:24]位为“1010”(0xeaffffff)时,表示B跳转指令,为“1011”时,表示BL跳转指令;[23:0]表示偏移地址。
从反汇编中可以看到 bl disable_watch_dog 的机器码是eb00000a ,二进制为1110 1011 000000000000000000001010。
其中1110表示无条件执行,接下的1011就是BL指令,如L==0则就表示B指令,剩下的Offset就是链接位。
BL指令的跳转地址计算:
1.如上图所示,先将24位Offset补码左移两位,得到 =0X28
2.由于ARM流水线,当前PC永远等于PC+8,所以PC=PC+0X28+8=0X30000004+0X28+=0X30000034。
若这里的PC值为其它值,算出来的转移地址也会随之改变,所以BL指令为地址无关码,跳转地址与位置无关。
注:ARM9是3级流水线,也就是PC处理时正在执行第1条指令的同时对第2条指令进行译码,并将第3条指令从存储器中取出,如下图所示,PC总是指向第3条指令取值的地方。

汇编指令-位置无关码(BL)与绝对位置码(LDR)(2)的更多相关文章
- JZ2440开发笔记(9)——位置无关代码设计【转】
b MAIN 和 ldr pc,=MAIN 的区别(谈到代码位置无关性) 看bootloader的时候经常看到这两种写法,不太明白区别,网上查了查.其实看了之后还是一头雾水? 其中,2和3 似乎是一个 ...
- 韦东山yy公开课笔记(2)--汇编,段,栈,重定位/链接地址,位置无关吗
1. 要不要学习汇编 可以只懂一点,工作中基本不用,一旦用就是出了大问题 ldr : load 读内存 ldr r0, [r1] : r1里存放的是地址值, 去这个地址读取4字节的内容,存入r0 s ...
- s3c2440裸机-代码重定位、清bss的改进和位置无关码
1.代码重定位的改进 用ldr.str代替ldrb, strb加快代码重定位的速度. 前面重定位时,我们使用的是ldrb命令从的Nor Flash读取1字节数据,再用strb命令将1字节数据写到SDR ...
- 代码重定位和位置无关码——运行于nor flash
通过前面的学习,我们知道,把可执行程序从一个位置复制到另一个位置的过程叫做重定位. 现在有两种方式,第一种是只重定位data段到内存(sdram),为什么需要重定位?因为有些flash的写操作,不是简 ...
- 关于ARM指令中位置无关和位置相关代码的认识【转】
本文转载自:https://blog.csdn.net/talent_CYJ/article/details/50533153 今天在一个问题上折腾了又是半天.就是在学JZ2440串口通信的时候,在s ...
- 经常使用ARM汇编指令
一面学习,一面总结,一面记录. 以下是整理在网上找到的一些资料,简单整理记录一下,方便以后查阅. ARM处理器的指令集能够分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.载入/存储指令. ...
- 常用ARM汇编指令
常用ARM汇编指令 [日期:2012-07-14] 来源:Linux社区 作者:xuyuanfan77 [字体:大 中 小] 在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时初 ...
- ARM 汇编指令
ARM汇编程序特点: l 所有运算处理都是发生通用寄存器(一般是R0~R14)的之中.所有存储器空间(如C语言变量的本质就是一个存储器空间上的几个BYTE).的值的处理,都是要传送到通 ...
- arm汇编指令总结(不断更新)
/** ****************************************************************************** * @author Maox ...
随机推荐
- nodejs01--什么是nodejs,nodejs的基本使用
nodejs使用范围 -直接在cmd命令行运行,在你的电脑上直接运行 -可以搭建一个web服务器(express,koa) -一些基本的使用 -modules是如何工作的 -npm管理modules ...
- VS2013+MFC串口控件的简单上位机
因为做东西,正好用到这里.所以就上传了文件分享一下. 利用VS带的MFC库,用起来还是比较方便的.空间的程序构架都是自动生成的,具体的程序自己加进去就行. 里面有整个的工程 还带有一个生成的EXE文件 ...
- 阿里云直播SDK - .NET
阿里云sdk:https://develop.aliyun.com/sdk/csharp?spm=5176.doc27234.2.4.QiJb9l Github:https://github.com/ ...
- NYOJ 289 苹果(01背包)
苹果 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 ctest有n个苹果,要将它放入容量为v的背包.给出第i个苹果的大小和价钱,求出能放入背包的苹果的总价钱最大值. ...
- Angular 小试牛刀[1]:Getting Started
首先,Angular2 与 Angular1.x 版本没有多大关系,甚至可以说是两个完全不一样的框架,故 Angular 指的是 Angular2 及以上的版本.而 Angular 与 TypeScr ...
- Java入门——(4)多线程
关键词:线程.Thread.Runnable.sleep().yield().join().同步 一.线程的概述 在一个操作系统中,每个独立执行的程序都可以称为一个进程,也就是"正在 ...
- 横截面数据分类——基于R
参考资料: <复杂数据统计方法>&网络&帮助文件 适用情况:在因变量为分类变量而自变量含有多个分类变量或分类变量水平较多的情况. 一. (一)概论和例子 数据来源:http ...
- iOS组件化方案的几种实现
最近研究了一下项目的组件化,把casa.bang.limboy的有关组件化的博客看了一遍,学到了不少东西,对目前业界的组件化方案有了一定的了解.这些高质量的博客大致讨论了组件化的三种方案:url-bl ...
- 再学python类(终结篇)
续写 初学python类,这几天吃坏东西了,拖着虚弱的身躯写的.有些乱请各位看官海涵. 声明:本人编程新手,还在学习中.所表述的东西都是基础语法之类的,分享我的学习笔记.还望多多指点,我一定虚心接受. ...
- async简单使用
node的异步io虽然好用,但是控制异步流程确实一个比较麻烦的事情,比如在爬虫中控制并发数量,避免并发过大导致网站宕机或被加入黑名单.因此需要一个工具来控制并发,这个工具可以自己写或者使用async( ...