ARM体系结构——ARM指令2——多寄存器内存访问与栈

ARM体系结构与接口技术——ARM指令2——多寄存器内存访问与栈

  • 栈的概念:
    • 栈的本质就是一段内存,程序运行时用于保存一些临时数据。
    • 如局部变量、函数的参数、返回值、以及程序跳转时需要保护的寄存器等。
  • 栈的分类
    • 增栈:压栈时栈指针越来越大,出栈时栈指针越来越小。
    • 减栈:压栈时栈指针越来越大,出栈时栈指针越来越小。
    • 满栈:栈指针指向最后一次压入到栈中的数据,压栈时需要先移动栈指针到相邻位置然后再压栈。
    • 空栈:栈指针指向最后一次压入到栈中的数据的相邻位置,压栈时可直接压栈,之后需要将栈指针移动到相邻位置。
  • 栈分为空增(EA)、空减(ED)、满增(FA)、满减(FD)四种。
  • ARM处理器一般使用满减栈。

 

ARM多寄存器内存访问

@ 多寄存器内存访问

.text
.global _start
_start:

    MOV R1,#1
    MOV R2,#2
    MOV R3,#3
    MOV R4,#4
    
    MOV R11,#0x40000020
    
    @STM R11,{R1-R4}        @ 将R1到R4寄存器中的数据存储到内存,以R11为起始地址的内存中
    @LDM R11,{R6-R9}        @ 将以R11为起始地址的内存中的数据,存储到R6-R9寄存器

    @ STM指令+后缀可以完成不同的寻址方式
    @ I和D代表寄存器保存的地址自动增长和字段降低
    @ A和B代表寄存器 存储内存之后变化 和 存储内存之前变化
    
    @STMIA R11!,{R1-R4}        @ 先存储再增长地址
    @STMIB R11!,{R1-R4}        @ 先增长地址再存储
    @STMDA R11!,{R1-R4}        @ 先存储再降低地址
    @STMDB R11!,{R1-R4}        @ 先降低地址再存储
STOP:
    B STOP
    
.end

基于起始地址为0x40000020,存储4个字节,4种寻址方式:

 


寄存器的内存访问实现栈

@ 寄存器的内存写入和读取操作就是栈的实现
.text .global _start
_start: @MOV R1,#1 @MOV R2,#2 @MOV R3,#3 @MOV R4,#4 @MOV R11,#0x40000020
   @ 前面提到ARM一般使用的是满减栈,与之对应的寄存器访问寻址方式就是SMTDB和LDMIA @STMDB R11!,{R1-R4} @ 先降低寄存器地址,再存储到内存 @LDMIA R11!,{R6-R9} @ 先存储数据到寄存器,再增长地址
   @ 编译器可以实现替换的功能,直接使用满减栈后缀FD STMFD R11!,{R1-R4} @ 满减栈压栈,编译之后会换成STMDB LDMFD R11!,{R6-R9} @ 满减栈出栈,编译之后会换成LDMIA
STOP: B STOP .end

栈的应用——C语言函数调用

@ 栈的应用:函数调用

.text
.global _start
_start:

    
    MOV SP,#0x40000020        @ 初始化栈指针
MAIN:
    MOV R1,#3
    MOV R2,#5
    BL FUNC1
    ADD R3,R1,R2
    B STOP

FUNC1:
    STMFD SP!,{R1,R2,LR}        @ 压栈保护现场
    MOV R1,#10
    MOV R2,#20
    SUB R3,R2,R1
    BL FUNC2
    LDMFD SP!,{R1,R2,LR}        @ 出栈恢复现场
    MOV PC,LR
    
FUNC2:
    STMFD SP!,{R1,R2,LR}        @ 压栈保护现场
    MOV R1,#10
    MOV R2,#20
    ADD R3,R2,R1
    LDMFD SP!,{R1,R2,LR}        @ 出栈恢复现场
    MOV PC,LR
    
STOP:
    B STOP
    
.end

 


 

END

 

 
posted @ 2022-04-18 16:45  zj城城城城  阅读(258)  评论(0编辑  收藏  举报