汇编之加载存储指令

文章目录

  • 加载指令:将数据由内存拿到寄存器
  • 存储指令:将数据由寄存器写回内存

单寄存器加载存储指令

z80 复制代码
mov r0, #0x48000000
ldr r1, [r0] @[r0]---->r1
str r1, [r0] @r1------>[r0]
z80 复制代码
ldr{cond} <rd>, 地址模式
ldr r1, [r0] @[r0]---->r1 [r0]等价于*p
-----------------------------------------
ldr r1, [r0,#0x08] @[r0+0x08]--->r1
ldr r1, [r0,r2] @[r0+r2]----->r1
ldr r1, [r0,r2, lsl #2] @[r0+r2*4]---->r1
------------------------------------------
ldr r1, [r0,#0x08]! @[r0+0x08]--->r1 r0=r0+0x08
ldr r1, [r0,r2]! @[r0+r2]----->r1 r0=r0+r2
ldr r1, [r0,r2, lsl #2]! @[r0+r2*4]---->r1 r0=r0+r2*4
-----------------------------------------------------
ldr r1, [r0], #0x08 @[r0]----->r1 r0=r0+0x08
ldr r1, [r0], r2 @[r0]----->r1 r0=r0+r2
ldr r1, [r0], r2, lsl #2 @[r0]--->r1 r0=r0+r2*4
ldr{cond}b r1, [r0] @将0x48000000内存中一个字节加载到r1,高位补0
ldr{cond}sb r1, [r0] @将0x48000000内存中一个字节加载到r1,高位补符号位
ldr{cond}h r1, [r0] @将0x48000000内存中两个字节加载到r1,高位补0
ldr{cond}sh r1, [r0] @将0x48000000内存中两个字节加载到r1,高位补符号位
z80 复制代码
.text
.global _start

_start:

  mov r0, #0x100
  ldr r1, [r0]
  mov r2, #0xfc
  add r1, r1, r2
  str r1, [r0]
  
  ldrb r3, [r0]
  ldrsb r4, [r0]
  
  mov r2, #0x80
  strb r2, [r0, #1]
  ldrh r5, [r0]
  ldrsh r6, [r0]
  b .
  
.data
  .space 1024
.end
  • 练习:将地址0x100开始的连续64字节数据拷贝到地址0x200位置处
z80 复制代码
.text
.global _start
_start:
  mov r0, #0x100
  mov r1, #16
  mov r2, #1
init:
  str r2, [r0], #0x04
  add r2, r2, #1
  subs r1, r1, #1
  bne init
  
  mov r0, #0x100
  mov r3, #0x200
  mov r1, #16
memcpy:
  ldr r2, [r0], #4
  str r2, [r3], #4
  sub r1, r1, #1
  cmp r1, #0
  bne memcpy
  
  b .
.data
  .space 1024
.end

多寄存器加载存储指令

z80 复制代码
ldm{cond}XX <Rd>{!} <registers>{^}
stm{cond}XX <Rd>{!} <registers>{^}
  cond, 可以条件执行
  XX:地址模式 默认IA
    IA, Increment After(先操作,后增加)
    IB, Increment Before(先增加,后操作)
    DA, Decrement After (先操作,后递减)
    DB, Decrement Before (先递减,后操作)
  !, 更新基址寄存器Rd
  registers, 寄存器列表 {r0,r2, r4-r8}
  ^, 指令中使用的寄存器都是用户模式下的寄存器
    若特权模式下的ldm指令, 且寄存器列表中包含PC寄存器, cpsr = spsr
  规律:编号低的寄存器对应低地址内存单元, 编号高的寄存器对应高地址内存单元
z80 复制代码
.text
.global _start
_start:
  mov r10, #0x100
  mov r0, #0x11
  mov r1, #0x22
  mov r4, #0x33
  
  @stmia r10, {r0,r1,r4}
  @stmib r10, {r0,r1,r4}
  @stmda r10, {r0,r1,r4}
  stmdb r10, {r0,r1,r4}
  b .
  
.data
  .space 1024
.end
  • 练习:使用多寄存器加载、存储指令将地址0x100开始的连续64字节数据拷贝到地址0x200位置处
z80 复制代码
.text
.global _start @将_start声明为全局的
_start:
  mov r0, #0x100
  mov r1, #16
  mov r2, #1
init:
  str r2, [r0], #0x04
  add r2, r2, #1
  subs r1, r1, #1
  bne init
  
  mov r0, #0x100
  mov r3, #0x200
  mov r1, #4
memcpy:
  ldmia r0!, {r4-r7}
  stmia r3!, {r4-r7}
  subs r1, r1, #1
  bne memcpy
  
  b .
.data
  .space 1024
.end

栈操作指令

  • 栈操作指令类似于多寄存器加载存储指令
z80 复制代码
ldm{cond}XX SP{!} <registers>{^}
stm{cond}XX SP{!} <registers>{^}
  XX, 地址模式 默认EA
    E, empty A, ascend F, full D, descend
    EA
    FA
    ED
    FD, 满减栈 ARM中默认使用。
push {r0, r3} 等价与 stmfd sp!, {r0,r3} 压栈
pop {r0, r3} 等价与 ldmfd sp!, {r0,r3} 弹栈
  • C语言中局部变量在栈中分配空间
c 复制代码
void func(void){
    int a = 0x123;
    int b = 0x456;
    int c = 0x789;
}
int main(void){
    func();
    return 0;
}
bash 复制代码
arm-linux-gnueabihf-gcc test.c -o test -marm
arm-linux-gnueabihf-objdump -D test >1.asm
vim 1.asm
相关推荐
浩浩测试一下1 小时前
汇编中的JCC指令 (逆向分析)
汇编·逆向·标志位·jcc指令·跳转指令·标志位寄存器
浩浩测试一下2 小时前
汇编中的段与段寄存器(大小)段序 (逆向分析)
汇编·逆向·二进制·字节序·windows编程·内存地址排序
楼兰公子7 小时前
嵌入式 Linux U-Boot 完整启动流程深度解析
arm·uboot
底层开发智库1 天前
无需硬件开发板,从零构建并运行ARM aemfvp-a-rme软件栈
arm开发·arm
浩浩测试一下1 天前
汇编 call与ret 函数与堆栈 (逆向分析)
汇编·push·函数·pop·call·ret·堆栈逆向
山屿落星辰1 天前
昇腾NPU算子开发:从“手写汇编“到“搭积木“
汇编
浩浩测试一下1 天前
汇编 汇编寻址 (逆向分析)
汇编·寻址·windows编程·二进制逆向·机器码
浩浩测试一下2 天前
汇编 位运算 (逆向分析)
汇编·逆向·位运算·asm·windows编程·二进制逆向
浩浩测试一下2 天前
汇编 高低八位寄存器数据存储方式(逆向分析)
汇编·网络安全·逆向·二进制·免杀·寄存器·windows编程
a83331962 天前
C语言嵌入汇编详解
汇编·单片机·语言