取当前eip 汇编_ARM汇编语言入门(四)

本文深入探讨ARM汇编中的内存指令,包括LDR和STR的使用,详细阐述了加载和存储数据的过程。讲解了三种偏移模式:立即数作为偏移量、寄存器作为偏移量和缩放寄存器作为偏移量,并举例说明了前变址寻址、后变址寻址以及PC相对寻址。此外,还提到了ARM中的立即数限制及其处理方法。
摘要由CSDN通过智能技术生成

c1e83a36284c4a6aa03ad0fd38802d39.png

Part 4 内存指令:加载和存储

ARM使用加载(Load)/存储(Stroe)指令来读写内存,这意味着你只能使用LDR和STR指令访问内存。在ARM上数据必须从内存中加载到寄存器之后才能进行其他操作,而在x86上大部分指令都可以直接访问内存中的数据。如前所述,在ARM上增加内存里的一个32-bit数据值,需要三个指令(load,increment,store)。为了解释 ARM 上的 Load 和 Store 操作的基本原理,我们从一个基本示例开始,然后再使用三个基本偏移形式,每个偏移形式具有三种不同的寻址模式。为了简单化,每个示例,我们将在同一段汇编代码中使用不同 LDR/STR 偏移形式的。遵循这本段教程的最佳方法是在你的测试环境中用调试器(GDB)运行代码示例。

  1. 偏移形式:立即数作为偏移量
  • 寻址模式:立即寻址
  • 寻址模式:前变址寻址
  • 寻址模式:后变址寻址
  1. 偏移形式:寄存器作为偏移量
  • 寻址模式:立即寻址
  • 寻址模式:前变址寻址
  • 寻址模式:后变址寻址
  1. 偏移形式:缩放寄存器作为偏移量
  • 寻址模式:立即寻址
  • 寻址模式:前变址寻址
  • 寻址模式:后变址寻址

第一个例子:

LDR 用于将内存中的值加载到寄存器中,STR 用于将寄存器内的值存储到内存地址。

cd2608ac66944ff05ceec0232d55f2e3.png
LDR R2, [R0]   @ [R0] - R0中保存的值是源地址。
STR R2, [R1]   @ [R1] - R1中保存的值是目标地址。

LDR : 把R0内保存的值作为地址值,将该地址处的值加载到寄存器R2中。

STR : 把R1内保存的值作为地址值,将寄存器R2中的值存储到该地址处。

下面是汇编程序的样子:

.data          /*.data段是动态创建的,无法预测 */
var1: .word 3  /* 内存中的变量var1=3*/
var2: .word 4  /* 内存中的变量var2=4*/
​
.text          /* 代码段开始位置 */ 
.global _start
​
_start:
    ldr r0, adr_var1  @ 通过标签adr_var1获得变量var1的地址,并加载到R0。
    ldr r1, adr_var2  @ 通过标签adr_var2获得变量var2的地址,并加载到R1。
    ldr r2, [r0]      @ 通过R0内的地址获取到该地址处的值(0x03),加载到R2。
    str r2, [r1]      @ 将R2内的值(0x03)存储到R1中的地址处。 
    bkpt             
​
adr_var1: .word var1  /* 变量var1的地址位置 */
adr_var2: .word var2  /* 变量var2的地址位置 */

在程序底部有我们的文本池(在代码段用来存储常量、字符串或其他可以引用的位置无关的偏移量),使用adr_var1adr_va2两个标签来存储var1var2的内存地址。第一个LDRvar1的地址加载到R0,然后第二个LDRvar2的地址加载到·。之后将R0中的地址指向的值(0x03)加载到R2,最后将R2中的值(0x03)存储到R1中的地址处。

当加载数据到寄存器中时,使用[]符号意思时:取寄存器中的值作为地址值,然后再从该地址处加载数据到目标寄存器中,如果不加[]那就是将寄存器中保存的值直接加载到目标寄存器。

同样STR命令中也是一个意思。

这听起来比实际要复杂的多,没关系,下面是一个更直观的演示图:

78b9082f7d0c2aabbd23937cf608fc42.gif

下面我们看一下调试器中的这段代码:

gef> disassemble _start
Dump of assembler code for function _start:
 0x00008074 <+0>:      ldr  r0, [pc, #12]   ; 0x8088 <adr_var1>
 0x00008078 <+4>:      ldr  r1, [pc, #12]   ; 0x808c <adr_var2>
 0x0000807c <+8>:      ldr  r2, [r0]
 0x00008080 <+12>:     str  r2, [r1]
 0x00008084 <+16>:     bx   lr
End of ass
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值