1> 源码test.c
-
#include <stdio.h>
-
-
int fool(int a,int b, int c, int d, int e, int f)
-
{
-
printf("%d->%d->%d->%d->%d->%d\n", a,b,c,d,e,f);
-
-
return a+b+c+d+e+f; //自动将返回值存入 r0 寄存器。
-
}
-
-
int main(void)
-
{
-
int ret;
-
-
__asm__ __volatile__(
-
-
"mov a1, #100\n\t"
-
"mov a2, #200\n\t"
-
"mov a3, #300\n\t"
-
"mov a4, #400\n\t"
-
-
"mov r5, #600\n\t"
-
"str r5, [sp,#-4]!\n\t" //sp寄存器里存放的是栈顶地址,4字节对齐
-
"mov r5,#500\n\t"
-
"str r5,[sp,#-4]!\n\t" //栈是满递减,先进后出,注意传参顺序。
-
-
"bl fool\n\t"
-
"add sp, #8\n\t" //恢复栈指针值,各子函数恢复各自栈.
-
"mov %[ret], r0\n\t" //取出返回值
-
-
:[ret]"=&r"(ret)
-
:
-
:"r0","r1","r2","r3","r5"
-
);
-
-
printf("ret: %d,Come back to %s.\n", ret, __func__);
-
-
return 0;
-
}
编译:arm-linux-gcc test.c
运行:
[root@FriendlyARM
/mnt]# ./a.out
100->200->300->400->500->600
ret:
2100,Come back to main.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2> 指令注解:
1》"str r5, [sp,#-4]!\n\t"
数据存储指令:将r5中的数据存储到【sp,#-4】地址的内存中;
【sp, #-4】:地址前索引:指令执行前,把偏移量【-4 + sp】作为寻址的地址。
!:指令执行完后将【sp-4】地址写回sp。
2》"bl fool\n\t"
带返回的跳转指令: 在跳之前,将pc的当前内容(也就是下下一条指令地址)保存到lr中。
所以,fool函数执行完后,将lr中的值重新赋给pc,就返回到27行,开始继续执行。
阅读(2011) | 评论(0) | 转发(0) |