ARM指令STMFD和LDMFD、PUSH和POP区别深入详解
根据上一篇文章,https://blog.****.net/tabactivity/article/details/90449317,我们编写了一个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