ARM指令adr和ldr的区别

发布者:心若澄明最新更新时间:2020-03-25 来源: eefocus关键字:ARM指令  adr  ldr 手机看文章 扫描二维码
随时随地手机看文章

很多人在写简单的裸机代码或分析uboot时,常常遇到adr和ldr指令。却分不清这2者的区别,现在谈谈adr与ldr指令。先写启动代码start.S。


.text

.globl _start

_start:

    ldr r0, test

    adr r0, test

    ldr r0, =test

    nop

test:

    nop

Makefile文件内容如下:


all : start.S

arm-linux-gcc -c -o start.o start.S

arm-linux-ld -Ttext 0x00000000 -g start.o -o start_elf

arm-linux-objcopy -O binary -S start_elf start.bin

arm-linux-objdump -D -m arm start_elf > start.dis

clean:

rm -f *.dis  *.bin  start_elf  *.o

反汇编start.S得到start.dis:


file format elf32-littlearm

Disassembly of section .text:

00000000 _start:

0: e59f0008 ldr r0, [pc, #8]; 10 test

4: e28f0004 add r0, pc, #4; 0x4

8: e59f0004 ldr r0, [pc, #4]; 14.text+0x14

c: e1a00000 nop (mov r0,r0)

 

00000010 test:

10:e1a00000 nop (mov r0,r0)

14:00000010 andeq r0, r0, r0, lsl r0


1、先分析第一条指令ldr r0,test被编译成ldr r0, [pc, #8],即到当前PC+8的存储器取值,运行第一条指令时,PC其实已经是8了(流水线决定的)。那么8+8等于0x10,所以r0等于e1a00000,此指令的作用就是读取test地址处存放的值。由于此处放了一条nop,即得到nop的机器码。


2、第二条adr r0,test被编译成add r0, pc, #4 这显然是依赖程序执行到此处的PC值。ADR是小范围地址读取伪指令,会将基于PC 相对偏移的地址值读取到寄存器中,此指令在4地址,PC是4+8=0xc再加4,于是r0=0x10。从结果上来看,test自身的值(标号值),被读到了r0,这个值是以PC为参考的,也就是test对应的指令(第二个nop)当前的地址。r0=(标号test的地址与此指令的距离差)+(此指令的地址)=((0x10-0x4=12)+(4))=16=0x10。假如在0x30000000以上运行,r0=((12)+(0x30000004))= 0x30000010。


3、ldr r0,=test被编译成两个字,一个指令,一个文字池。执行到这里PC=8, 8+8+4=0x14,所以在14地址取值,编译器在14地址处放了0x00000010,0x00000010是test的值,假如在Makefile指定连接地址是0x30000000,那么编译器放在这里的就是0x30000010,可见,这个值是编译时确定的。最后一行andeq r0, r0, r0, lsl r0大概是编译器的机械动作,把一个数字翻译成了指令。

关键字:ARM指令  adr  ldr 引用地址:ARM指令adr和ldr的区别

上一篇:tiny4412开发板GPIO试验
下一篇:tiny4412裸机程序之位置无关码

推荐阅读最新更新时间:2024-11-13 13:31

汇编指令-MOV与ldr区别
MOV   1.可以寄存器与寄存器之间传递数据   2.可以把立即数移动到寄存器中(常数不能超过32位) LDR   1.可以地址与寄存器之间的数据传递   2.也可以常数传递到寄存器中 实例:   1.r1与r2寄存器之间传递就只能用MOV: MOV r1,r2   2.常数传递到寄存器可以使用MOV和ldr: MOV r0,#0 ldr r0,=0   3.寄存器与地址0X00000000之间传递数据只能用ldr: ldr r0,=0X30000000 ldr r0,0X00000000 LDR指令: ldr r0, 0x12345678 // 就是把0x12345678这个地址中的值
[单片机]
ARM指令LDR指令
ARM指令集中,LDR通常都是作加载指令的,但是它也可以作伪指令。 (1)LDR r0,=name,像这种带等号的是伪指令,而不是ARM指令,LDR 伪指令用于加载立即数或一个地址值到指定寄存器. *如果name是立即数的话:LDR R0,=0X123; //将0X123存入R0 *如果name是个标识符:LDR R0,=NAME; //将NAME的地址存入R0 相当于: LDR R0,LABEL; LABEL DCB NAME;//分配内存并用NAME初始化(LABEL为内存的起始地址?) (2)LDR R1, ;如果没有等号,LDR 指令用于从内存中读取数据放入寄存器中.该指令是 将R0 地址处的数据读
[单片机]
ARM汇编中ldradr的区别
ldr r0, _start adr r0, _start ldr r0, =_start nop mov pc, lr _start: nop 编译的时候设置 RO 为 0x0c008000 0c008000 _start-0x14 : c008000: e59f000c ldr r0, ; c008014 _start c008004: e28f0008 add r0, pc, #8 ; 0x8 c008008
[单片机]
ARM指令集 VS Thumb指令集
1 thumb指令集概述 为兼容数据总线宽度为16位的应用系统,ARM体系结构除了支持执行效率很高的32位ARM指令集以外,同时支持16位的Thumb指令集。 Thumb指令集是ARM指令集的一个子集,是针对代码密度问题而提出的,它具有16位的代码宽度。与等价的32位代码相比较,Thumb指令集在保留32位代码优势的同时,大大的节省了系统的存储空间。Thumb不是一个完整的体系结构,不能指望处理器只执行Thumb指令集而不支持ARM指令集。 当处理器在执行ARM程序段时,称ARM处理器处于ARM工作状态,当处理器在执行Thumb程序段时,称ARM处理器处于Thumb工作状态(CPSR的T=0:arm,T=1:thumb)。
[单片机]
arm汇编—ldr伪指令
操作系统:ubuntu10.04 汇编语言:arm 1,ldr加载指令 LDR指令的格式为:LDR{条件} 目的寄存器, 存储器地址 LDR指令用亍从存储器中将一个32位的字数据传送到目的寄存器中。该指令通常用亍从存储器中读取32位的字数据到通用寄存器,然后对数据迕行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。该指令在程序设计中比较常用,丏寻址方式灵活多样,请读者认真掌握。 指令示例:LDR R0, ; 将存储器地址为R1的字数据读入寄存器R0。 LDR R0, ;将存储器地址为R1+R2的字数据读入寄存器R0。 LDR R0, ;将存储器地
[单片机]
ARM中MOV与LDR的区别
ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令。 比如想把数据从内存中某处读取到寄存器中,只能使用ldr 比如: ldr r0, 0x12345678 就是把0x12345678这个地址中的值存放到r0中。 而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立即数移动到寄存器中,这个和x86这种CISC架构的芯片区别最大的地方。 x86中没有ldr这种指令,因为x86的mov指令可以将数据从内存中移动到寄存器中。 另外还有一个就是ldr伪指令,虽然ldr伪指令和ARM的ldr指令很像,但是作用不太一样。ldr伪指令可以在立即数前加上=,以表示把一个地址写到某寄存器中,比
[单片机]
arm指令ldr 和 mov的区别
ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令。 比如想把数据从内存中某处读取到寄存器中,只能使用ldr 比如: ldr r0, 0x12345678 就是把0x12345678这个地址中的值存放到r0中。 而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立即数移动到寄存器中,这个和x86这种CISC架构的芯片区别最大的地方。 x86中没有ldr这种指令,因为x86的mov指令可以将数据从内存中移动到寄存器中。 另外还有一个就是ldr伪指令,虽然ldr伪指令和ARM的ldr指令很像,但是作用不太一样。ldr伪指令可以在立即数前加上=,以表示把一个地址写到某寄存器中,
[单片机]
ARM LDR/STR, LDM/STM 指令
这里比较下容易混淆的四条指令,已经在这4条指令的混淆上花费了很多精力,现在做个小结,LDR,STR,LDM,STM这四条指令, 关于LDM和STM的说明,见另外一个说明文件,说明了这两个文件用于栈操作时的注意事项。 (1)LDR:L表示LOAD,LOAD的含义应该理解为:Load from memory into register。下面这条语句就说明的很清楚: LDR R1, ; R1 就是把R2所指向的存储单元的内容的值(一个memory地址内的值),读取到R1中(一个register) (2)STR:S表示STORE,STORE的含义应该理解为:Store from a register into memor
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved