您的位置:首页 > 编程语言

位置无关代码码与位置相关代码

2014-09-20 17:58 295 查看
位置无关代码码与位置相关代码

位置无关与位置相关代码是关于arm程序在跳转时的寻址方式的两种,一般情况下两种方法都能达到跳转到目的地址的目标,但是在某些特定的环境下,两种跳转方法得到的结果相关较大。

位置无关代码的跳转可通过“B或BL 标号”命令执行,当执行B或BL命令实现跳转时,实际的二进制代码在跳转时是执行:计算可执行代码中目标地址到当前PC值处的距离,然后把该距离值加上当前的PC值,然后赋值给PC寄存器实现跳转,该跳转方法由于指令的地址域只有26位,所以它只能向前/向后寻址32M位地址,如果目标地址到当前PC值的距离大于该值时,可使用伪指令“ADR和ADRL PC,=标号地址”实现跳转,实际执行过程是先计算目标址址到当前PC的距离,然后把当前PC值加上距离值赋值到目标寄存器PC中,实现跳转,ADR与B或BL功能类似,但ADRL可以实现全部范围内的跳转,其通过把目标地址与当前PC的距离值存储到一个缓存字中,然后把缓存字中的值加载到寄存器PC中。

位置相关跳转也可以叫绝对位置跳转,一般使用伪指令LDR PC,=label实现跳转到label标号的链接地址中,绝对地址也就是链接地址。这里位置相关及位置无关本质上的区别其实是链接地址与运行地址的区别。

在无操作系统中的裸机代码中,如果链接的偏移基址为0,则绝对位置跳转与相对位置跳转的效果是一样的,而对于一些把可执行代码拷贝到ram中再运行的程序中,链接地址与起始运行地址是不相同的,一般地链接地址是一个ram逻辑地址内的一个数值,而运行地址则是代码烧写的flash等存储器件的逻辑地址,一般是0地址。链接的偏移地址可以通过在编译时通过在链接脚本或Makefile中指定。

在完成可执行代码从flash到ram的拷贝后,通过LDR PC,=label指令跳转到内存中执行程序,而在这之前执行的代码跳转必须是位置无关的,否则会出现跑飞的异常。

B label BL label //位置无关跳转到label

ADR R0,label ADRL R0,=label //获取label到当前程序的偏移距离

ADR PC,label ADRL PC,=label //位置无关跳转到label

LDR PC,=label //位置相关的绝对位置跳转

LDR R0,=label //获取label到当前程序的偏移距离,注意这里不是获取label的(链接地址)绝对地址

LDR R0,=0x500000C0

LDR R1,[R0]

LDR R2,=0x00

STR R2,[R0]

LDR R0,=label加载label数据到寄存器R0中,如果label大于255则把LDR翻译成上述位置无关的伪指令,如果小于255则直接是用LDR指令进行立即数寻址方式

参考文档

http://blog.chinaunix.net/uid-10696433-id-2935776.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: