ARM指令STMFD和LDMFD、PUSH和POP区别深入详解

根据上一篇文章,ARM的STM和LDM指令详解_arm stm指令-CSDN博客,我们编写了一个ARM汇编示例

main.c

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>

extern int asm_add(int, int);

int main(int argc, char* argv[]){
	int a = 13;
	int b = 2;
	int result = asm_add(a, b);
	printf("hello, arm7 ! result=%d", result);
	return 0;
}

calc.S

 AREA CLAC, CODE,READONLY
 EXPORT asm_add

asm_add PROC
 MOV R2, #0x7
 MOV R3, #0x9
 PUSH {R0-R1} ;将R0-R1入栈
 STMFD SP!, {R3, R2, R1, R0} ;将R0-R3 保存到堆栈
 NOP
 POP {R4-R5}  ;出栈两个,保存到R4, R5。这.
 LDMFD SP!, {R6-R8} ;数据出栈,放入R6-R8

 ADD R0, R1
 BX LR
 ENDP

 END

上面的程序运行后R4、R5、R5、R6、R7、R8分别是多少?

我们先来看下Debug寄存器数值和calc反汇编:

通过反汇编,可以看到,我们的STMDF和LDMFD分别翻译为PUSH和POP了。堆栈还是那个堆栈,后进先出。一开始

R0 = 13,R1=2, R2=7,R3 =9 。

 PUSH {R0-R1} ;将R0-R1入栈
 STMFD SP!, {R3, R2, R1, R0} ;将R0-R3 保存到堆栈

将R1、R0、R3、R2、R1、R0入栈,堆栈为:

13、2、7、9、13、2 (栈顶-》栈底)  

{R3, R2, R1, R0} 里,寄存器大的会先入栈

 POP {R4-R5}  ;出栈两个,保存到R4, R5。这.
 LDMFD SP!, {R6-R8} ;数据出栈,放入R6-R8

接着POP,R4 = 13 ,R5 = 2,R6 = 7,R7 = 9,R8 = 13

-------------------

如果想在NDK中嵌入ARM汇编,可以:

__attribute__((optnone))  void xxxx(){
    __asm__  (        
 
        "MOV R0, #0xD\n"
        "MOV R1, #0x2\n"        
        "PUSH {R1, R0}\n"
        "MOV R2, #0x7\n"
        "MOV R3, #0x9\n"
        "STMFD SP!, {R3, R2, R1, R0}\n"
        "POP {R4-R5}\n" 
        "LDMFD SP!, {R6-R9}\n" 
    );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江西省遂川县常驻深圳大使

喜欢本文,打赏下作者吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值