ldr与adr的区别
参考:
http://coon.blogbus.com/logs/2738861.html
http://hi.baidu.com/for_guanghui/item/73e60bbcc8be15a2eaba938b
ldr r0, _start
adr r0, _start
ldr r0, =_start
nop
mov pc, lr
_start:
nop
编译的时候设置 RO 为 0x0c008000
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
0c008000 <_start-0x14>:
c008000: e59f000c ldr r0, [pc, #12] ; c008014 <_start>
c008004: e28f0008 add r0, pc, #8 ; 0x8
c008008: e59f0008 ldr r0, [pc, #8] ; c008018 <_start+0x4>
c00800c: e1a00000 nop (mov r0,r0)
c008010: e1a0f00e mov pc, lr
0c008014 <_start>:
c008014: e1a00000 nop (mov r0,r0)
c008018: 0c008014 stceq 0, cr8, [r0], -#80
分析:
ldr r0, _start
从内存地址 _start 的地方把值读入。执行这个后,r0 = 0xe1a00000
adr r0, _start
取 得 _start 的地址到 r0,但是请看反编译的结果,它是与位置无关的。其实取得的时相对的位置。例如这段代码在 0x0c008000 运行,那么 adr r0, _start 得到 r0 = 0x0c008014;如果在地址 0 运行,就是 0x00000014 了。
ldr r0, =_start
这 个取得标号 _start 的绝对地址。这个绝对地址是在 link 的时候确定的。看上去这只是一个指令,但是它要占用 2 个 32bit 的空间,一条是指令,另一条是 _start 的数据(因为在编译的时候不能确定 _start 的值,而且也不能用 mov 指令来给 r0 赋一个 32bit 的常量,所以需要多出一个空间存放 _start 的真正数据,在这里就是 0x0c008014)。
因此可以看出,这个是绝对的寻址,不管这段代码在什么地方运行,它的结果都是 r0 = 0x0c008014
1、ADR伪指令--- 小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
ADR伪指令格式 :ADR{cond} register, expr
地址表达式expr的取值范围:
当地址值是字节对齐时,其取指范围为: +255 ~ 255B;
当地址值是字对齐时,其取指范围为: -1020 ~ 1020B;
2、ADRL伪指令----中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。
ADRL伪指令格式:ADRL{cond} register, expr
地址表达式expr的取值范围:
当地址值是字节对齐时,其取指范围为: -64K~64K;
当地址值是字对齐时,其取指范围为: -256K~256K;
3、LDR伪指令-----大范围的地址读取
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。
ldr与adr的区别的更多相关文章
- ldr和adr在使用标号表达式作为操作数的区别
ARM汇编有ldr指令以及ldr.adr伪指令,他门都可以将标号表达式作为操作数,下面通过分析一段代码以及对应的反汇编结果来说明它们的区别. ldr r0, _start adr r0 ...
- LDR 和 ADR 彻底详解
0.什么是位指令? 答:伪指令(Pseudo instruction)是用于告诉汇编程序如何进行汇编的指令.它既不控制机器的操作也不被汇编成机器代码, 只能为汇编程序所识别并指导汇编如何进行. 1.L ...
- LDR 和MOV 指令区别
ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令.比如想把数据从内存中某处读取到寄存器中,只能使用ldr比如:ldr r0, 0x12345678就 ...
- 8.adr与ldr伪指令的区别
ldr和adr都是伪指令,区别是ldr是长加载.adr是短加载. 重点:adr指令加载符号地址,加载的是运行时地址: ldr指令加载符号地址时,加载的是链接地址.
- (转)为什么adrl r2,mem_cfg_val这里不用ldr r2,=mem_cfg_val
网址:http://blog.csdn.net/glorin/article/details/6327083 memsetup:mov r1, #MEM_CTL_BASEadrl r2,mem_cfg ...
- JZ2440开发笔记(9)——位置无关代码设计【转】
b MAIN 和 ldr pc,=MAIN 的区别(谈到代码位置无关性) 看bootloader的时候经常看到这两种写法,不太明白区别,网上查了查.其实看了之后还是一头雾水? 其中,2和3 似乎是一个 ...
- ARM学习笔记9——ARM汇编汇编语言中的伪指令
ARN汇编器支持ARM伪指令,这些伪指令在汇编阶段被翻译成ARM或Thumb指令.ARM伪指令包含ADR.ADRL.MOV32和LDR.一.ADR伪指令 1.作用 ADR是小范围地址读取伪指令,基于P ...
- STM32学习之路入门篇之指令集及cortex——m3的存储系统
STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码 操作数1, 操作数2,... ...
- ARM体系结构和汇编指令
第一节 可编程器件的编程原理 1. 可编程器件的特点 1 . CPU在固定频率的时钟控制下节奏运行 2 . CPU可以通过总线读取外部存储设备中的二进制指令集,然后解码执行 3 . 这些可以被CPU解 ...
随机推荐
- JVM内存模型 三
本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏 1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉 ...
- 【BZOJ3670】【NOI2014】动物园 [KMP][倍增]
动物园 Time Limit: 10 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 近日,园长发现动物园中好吃懒做的动物 ...
- 【洛谷 P3304】[SDOI2013]直径(树的直径)
题目链接 题意,求一棵树被所有直径经过的边的条数. 这题是我们8.25KS图论的最后一题,当时我果断打了暴力求所有直径然后树上差分统计的方法,好像有点小问题,boom0了. 考完改这题,改了好久,各种 ...
- webstorm vue代码修改后不更新问题
把 safe write 的勾去掉就行了.
- 为什么VS没有提供平win64程序编写项
最近在学习C++和MFC编程,突然有个疑问,为什么每次新建项目时,都只有win32 console application,从来没见过win64的选项,于是去网上查了查,下面是我找到的几个答案: 作者 ...
- linux中链表的使用【转】
转自:http://blog.csdn.net/finewind/article/details/8074990 Linux下链表的使用方法跟我们常规的不一样,通常情况下,链表的next指针都指向节点 ...
- shell脚本(傻瓜式处理文件到指定分类)
前言 每一到两周,我大概会新增十多个甚至更多的资料文件,都是些最近遇到的一些问题的总结或者相关技术文档,但是资料都是在公司电脑上,拷贝到自己电脑上后,又得一个个去找一个这个应该放到哪个分类,个人感觉很 ...
- python 多进程锁Lock和共享内存
多进程锁 lock = multiprocessing.Lock() 创建一个锁 lock.acquire() 获取锁 lock.release() 释放锁 with lock: 自动获取.释放锁 类 ...
- [ nginx ] 代理后端tomcat 无法显示图片报错:ERR_CONTENT_LENGTH_MISMATCH
问题日志如下:
- BAT 前端开发面经 —— 吐血总结
更好阅读,请移步这里 聊之前 最近暑期实习招聘已经开始,个人目前参加了阿里的内推及腾讯和百度的实习生招聘,在此总结一下 一是备忘.总结提升,二是希望给大家一些参考 其他面试及基础相关可以参考其他博文: ...