ARM数据加载与存储指令 (二) 文字池中常量数据加载的反汇编实例以及参考文字池加载指令 LDR R1, [PC, #offset to ; Literal Pool 1],PC偏移加载表明ROM中

本文详细介绍了ARM处理器中数据加载与存储的指令使用,包括程序示例分析,以及如何利用LDR、ADR等指令加载常量和地址到寄存器。通过实例展示了不同指令在不同情况下的应用,如直接加载、伪指令加载等,并解释了汇编器如何处理这些指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ARM数据加载与存储指令 (二) 

2016-04-19 10:30

接上 与 (一)

完成下列任务

1.阅读程序exp6_2.s,写出程序的功能。设置代码段的基地址为0x8000。用AXD单步调试程序,观察每执行一步以后,相应的寄存器和存储器的变化情况,完成表格。

打开的process view窗口如下:register,disassembly,low lever symbols,memory

序号执行指令指令执行后变化情况
  寄存器存储器
  R0R1R2R3R4SPPC0x80240x80280x802C0x80300x8038 
0 0x00x00x00x00x00x00x80000x200x620x690x670x21 
1              
2              
3              
4              
5              
6              
7              
8              
9              
10              
                

答案:

1.程序的功能是计算给定数据各项和的平均值,方法是先将数据各项加载到寄存器中,然后利用数据处理指令计算,最后再讲结果存入寄存器中。

一、 综合编程

1.绘图分析多寄存器传送指令的各种模式,并设计程序验证。(学生作业)

IA:

数据起始地址:0x800C

 0x800C

0x10

0x80100x20
0x80140x30
 
R0R1
0x100x20
    

DB:

数据起始地址:0x8010

 0x8010

0x10

0x80140x20
0x80180x30
 
R0R1
0x100x20
    

FD:

数据起始地址:0x800C

 0x800C

0x10

0x80100x20
0x80140x30
 
R0R1
0x100x20
    

EA:

数据起始地址:0x8010

 0x8010

0x10

0x80140x20
0x80180x30
 
R0R1
0x100x20
    

二、 注意事项 (程序中加载常量和地址的方法)

实际编程的过程中,常需要把立即数常量和地址值载入寄存器,由于指令集长度的限制和存储/加载体系结构的特点,这两个问题需要专门说明。

区别:

START LDR R0,START 把START相对应的地址值的存储单元里的数据加载到R0,这条指令的结构就是R0里存储的是指令LDR R0,START对应的二进制代码。

LDR R0,=SRART 把START相对应的地址值加载到R0

ADR R0,START 把START相对应的地址值加载到R0

1. 加载常量到寄存器

(1) 使用MOV或MVN指令直接加载

直接加载任何取值在0x0~0xFF间的8位常量。

对上述的取值进行循环右移偶数次后的数值n

例子: MOV R1,#0x250

(2) 使用一种伪指令格式加载

使用一个LDR指令和在数字量前的等号,就可以很容易地将常量写入代码。

例子:LDR R1,=0x520

如果构造的常量能用MOV或者MVN指令加载,那么汇编器会采用适当的指令;否则,汇编器会产生一个带PC相对偏移地址的LDR指令来从文字池中读取常量。

文字池是为常量留出的一部分内存。

默认情况:在END指示的位置。在4kB范围内。

例6.1 [B1] 加载常量值(example1.s)

AREA example1,CODE

ENTRY

START

MOV R0,#0xFF ; (1)

MOV R0,#0xFF0 ; (2)

LDR R2,=0xFF0 ;(3)

LDR R3,=0x5C34D77D ;(4)

STOP

程序解读

(1) 常量在0x0~0xFF之间,可以采用MOV指令直接加载

(2) 常量0xFF0是将0xFF循环右移28位后的值,同样可以采用MOV指令直接加载。

(3) 常量0xFF0取值在MOV或MVN指令所能加载的取值范围之内,在AXD中通过反汇编可以看到汇编器产生了以下代码 MOV R2,#0xFF0

(4) 常量0x5C34D77D超出了取值范围,所以汇编器用DCD分配了一个字的内存来存放常量。这段内存就是一个文字池,其地址是0x8020。在ADX中通过反汇编可以看到汇编产生的一下代码印证了这一点。

LDR R3, #0x00008020 ;=#0x5C34D77D

...

0x8020 DCD 0x5C34D77D

2. 加载地址到寄存器

程序中常常要加载某个地址到寄存器中,伪指令ADR和ADRL的功能就是将一个寄存器相关表达式或程序相关表达式的地址存入寄存器中。

(1)用ADR或ADRL直接加载

所谓程序相关表达式就是标号相对于当前PC的偏移地址,而寄存器相关表达式就是标号相对于保存在指定的通用寄存器中的地址。一般的格式是:

ADR Rn,label

ADRL Rn,label

例6.2加载地址

AREA example2,CODE

ENTRY

START

ADR R0,START ;(1)

ADR R1,ADDR ;(2)

ADRL R2,ADDR+1000 ;(3)

STOP

B STOP

ADDR DCD 0x12345678

END

程序解读

(1) 代码(1)在AXD中通过反汇编可以看到汇编器产生以下代码

SUB R0,PC,#8 ;#0x8000

(2) 代码(2)在AXD中通过反汇编可以看到汇编器产生了一下代码

ADD R1,PC,#0x10 ;#0x801C

(3) 代码(3)在AXD中通过反汇编可以看到汇编器产生了一下代码

ADD R1,PC,#0x300 ;#0x8310

ADD R2,R2,#0xF4

由于标签ADDR的地址是0x801C,所以以上汇编器产生的指令将地址正确地加载到了寄存器中。

(2)使用一种伪指令格式加载(LDR)

注意:这里的LDR是伪指令,与加载指令不同。

LDR Rd,=label

与前述利用LDR指令加载常量到寄存器相似,这种格式也可以加载程序相关表达式到寄存器。实际上,汇编器会把label的地址放入文字池,并产生一个LDR指令从文字池上读取地址。

例6.3 加载label地址

AREA example3,CODE

ENTRY

START

BL ARNEW

STOP

B STOP

ARNEW

LDR R0,=START ;(2)

LDR R1,=ARNEW ;(3)

LDR R2,=ARNEW+100 ;(4)

END

(1) 这段程序将数值0x20026、START地址、ARNEW地址和ARNEW地址+100都放入了文字池,这样文字池就变成了

地址数据
0x80200x20026
0x80240x8000
0x80280x8010
0x802C0x8074

即在文字池的偏移地址为4处存放着START地址,偏移地址为8处存放着ARNEW地址,偏移地址为12(0xC)处存放着ANREW+100地址。

(2) 代码(2)把START的地址放入文字池,汇编器在地址0x8024处分配了1字的内存,存放0x8000,产生语句

LDR R0,[0x8024]

(3) 代码(3)把ARNEW的地址放入文字池,汇编器在地址0x8028处分配了1字的内存,存放0x8010,产生语句

LDR R0,[0x8028]

(4) 代码(4)把ARNEW+100的地址放入文字池,汇编器在地址0x802C处分配了1字的内存,存放0x8074,产生语句

LDR R0,[0x802C]

[B1]应用小结:

1. 数据在ARM指令允许的范围内,用MOV RX,#X

2. 数据超出范围,用LDR RX,=X。此时的LDR是一个伪指令。

https://www.sohu.com/a/70142457_119709

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值