Chinaunix首页 | 论坛 | 博客
  • 博客访问: 994074
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 216
  • 用 户 组: 普通用户
  • 注册时间: 2018-11-27 17:55
文章分类
文章存档

2019年(21)

我的朋友

分类: C/C++

2019-06-30 15:10:30


点击(此处)折叠或打开

  1. int son(int a, int b)
  2. {
  3.     int c = 0;

  4.     c = a + 2*b; //son函数执行一个相加操作

  5.     return c;
  6. }

  7. int main(int a)
  8. {
  9.     int i = 1, j = 0;

  10.     j = son(a,i);

  11.     return j;
  12. }
arm-linux-gcc -O1 call.c -S

汇编:
son:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
add r0, r0, r1, asl #1
bx lr
.size son, .-son
.align 2
.global main
.type main, %function
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
stmfd sp!, {r4, lr}  //把r4和lr寄存器压栈
mov r1, #1
bl son
ldmfd sp!, {r4, lr}  ////把r4和lr寄存器恢复
bx lr
.size main, .-main
.ident "GCC: (ctng-1.6.1) 4.4.3"
.section .note.GNU-stack,"",%progbits


==================
LDMFD和STMFD的理解

ARM里面的堆栈是满递减(FULL DESCENDING)的。SP指向最后一个入栈的数据,SP的地址由高向低生长。对于LDM和STM指令来说,编号小的寄存器对应堆栈中的低地址。


STMFD的寻址方式是事先递减方式(Decrease Before)。内存地址可以用下面的式子表示:

start_address=SP-(Number of register *4)

end_address=SP-4

举例来说:STMFD SP!,{R1-R7,LR}  //SP=0x48000060

入栈后各寄存器存放的地址如下图所示:

 

SP后面的!表示SP=SP-(Number of registers *4),在这里入栈后SP指向R1寄存器入栈的地址。

 

LDMFD的寻址方式是事后递增方式(Increase After)。内存地址可以用下面的式子表示:

start_address=SP

end_address=SP+(number of registers*4)-4

举例来说:LDMFD SP!,{R1-R7,LR}  //紧跟上例,SP=0x48000040

根据编号小的寄存器对应低地址的原则,0x48000040地址处的值出栈给R1寄存器,0x48000044地址处的值出栈赋给R2寄存器,依次类推。正好与STMFD一一对应。

SP后面的!表示要更新SP的值。SP=SP+(number of registers*4)。


阅读(2565) | 评论(0) | 转发(0) |
0

上一篇:C语言的ARM实现(四)SWITCH

下一篇:没有了

给主人留下些什么吧!~~