Arm汇编学习笔记(八)——寄存器的使用

ARM 459浏览

  • 在程序中,我们可以使用16个通用寄存器中的14个来保存自己的数据,r13和r15分别是sp和pc寄存器,我们无法使用。

  • ATPCS规定,栈指针应该是8字节对齐。

  • ATPCS规定,被调用函数必须保证在执行前和执行后r4-r11的内容不变,即被调用函数必须在开始保存r4-r11,返回前再恢复。如下图:

可以用下面的保存模版:

routine_name
                    STMFD sp!, {r4-r12, lr} ; stack saved registers
                    ; body of routine
                    ; the fourteen registers r0-r12 and lr are available
                    LDMFD sp!, {r4-r12, pc} ; restore registers and return

其中保存r12是为了栈指针8字节对齐。

  • ATPCS规定,函数调用过程中,r0-r3用于传递参数,超过4个的参数保存在栈中。返回值必须保存在r0中。

  • 多寄存器入栈出栈指令,示例LDM和STM,寄存器列表中的寄存器号必须是升序。

  • 双字的加载和存储指令,LDRD和STRD,操作数寄存器是相邻的两个寄存器,Rd和Rd+1,并且这个Rd的寄存器号必须是偶数。
  • Use register names rather than physical register numbers when writing assembly routines. This makes it easier to reallocate registers and to maintain the code. (不太明白什么意思,是不是用RN定义别名?)
  • 为了节省寄存器,我们可以将一些位数比较少的变量存储在一个寄存器中,然后通过位移操作就可以取出相应变量。看下面例子:
sample = table[index];
index += increment;

一般情况下,index和increment不会超过16位,我们就可以将它们两个存放到同一个寄存器中,如下图

上面C代码我们可以用下面汇编代码实现:

LDRB sample, [table, indinc, LSR#16] ; table[index]
ADD indinc, indinc, indinc, LSL#16 ; index+=increment