Chinaunix首页 | 论坛 | 博客
  • 博客访问: 35193
  • 博文数量: 14
  • 博客积分: 50
  • 博客等级: 民兵
  • 技术积分: 35
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-25 16:26
文章分类

全部博文(14)

文章存档

2015年(3)

2014年(2)

2013年(8)

2012年(1)

我的朋友

分类: 嵌入式

2013-07-28 16:17:05

原文地址:ARM汇编的堆栈使用规则 作者:graylocus

1.数据栈的类型
  数据栈有两个增长方向:向内存地址减小的方向增长,称为Descending栈;向内存地址增大的方向增长,称为Ascending栈
  栈的增长的本质,就是堆栈指针SP的移动。
  当栈指针指向栈顶元素(最后一个入栈的数据)时,称为FULL栈,当栈指针指向栈顶元素相邻的第一个空格数据单元时,称为EMPTY栈
  结合以上两点,栈的类型有4种:
 1.FD:full descending,满递减
 2.ED:empty descending,空递减
 3.FA:full ascending,满递增
 4.EA:empty ascending,空递增

 ATPCS规定数据栈为FD类型,并且对数据栈的操作是8字节对齐的。
 使用stmdb/ldmia批量内存访问指令来操作FD数据栈。
 
 stmdb,将寄存器的值保存到内存中的数据栈,这时,应该保证SP指针有效,所以要先减sp,叫做decrement before;
 ldmia,将内存中数据栈的内容恢复到寄存器,每次出栈时,sp指针所指的内存单元不能为空,所以要先使用sp,再增加sp的值,叫做increment after。
  
 使用实例:

点击(此处)折叠或打开

  1. ldm{cond} {!} {^}
  2. stm{cond} {!} {^}

  3. handleirq:
  4. sub lr,lr,#4
  5. stmdb sp!,{r0-r12,lr} @保存使用到的寄器,"!"使得指令执行后,sp=sp-14*4
  6. ldr lr,=int_return
  7. ldr pc,=irq_handle
  8. int_return:
  9. ldmia sp!,{r0-r12,pc}^  @"^"表示将spsr的值复制到cpsr
  10. @"!"表示指令执行后,sp=sp+14*4.
PS:ARM内存访问指令有两类,ldr/str,ldm/stm
  ldr指令是从内存中读取数据到寄存器,str指令是把寄存器的值存储到内存中,也可以保存到栈中。
  如:ldr sp,[r2] ; 
      str sp, [r1]
  ldm/stm是批量访问内存指令。
阅读(1191) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~