在ARM机器码中,SUB SP、SP、#36中的偏移量是如何编码的?

问题描述

编辑: 我关心的是 ARM 指令的编码方式。

让我们看看下面的例子:

  194640:   e92d40f0    push    {r4,r5,r6,r7,lr}
  194644:   e24dd024    sub sp,sp,#36 ; 0x24
  --> sp decrease 36 ~ 0x24 --> Is it calculated by e24dd024 & 0x0000ffff ?

  1995ec:   e92d4ef0    push    {r4,r9,sl,fp,lr}
  1995f0:   e24ddd0a    sub sp,#640    ; 0x280
  1995f4:   e1a04000    mov r4,r0
  --> sp decrease 640 ~ 0x280 --> How it is calculated ?

 Other examples:
  191ea8:   e92d4030    push    {r4,lr}
  191eac:   e24dd034    sub sp,#52 ; 0x34
  191eb0:   e28d5014    add r5,#20

  194f54:   e28d60a8    add r6,#168    ; 0xa8
  194f58:   e28d5e13    add r5,#304    ; 0x130

解决方法

  push    {r4,r5,r6,r7,lr}
  sub     sp,sp,#36 ; 0x24

这基本上是一个函数“序言”。
函数保留将要更改的寄存器(push 指令)并为函数内部变量和寄存器的中间保留保留堆栈(sub sp,...)。

所以简单来说,函数使用的变量越多,sp减去的数就越大。请注意,这也取决于变量的 sizeof(x)。假设函数声明了一个大的结构,那将需要更多的堆栈来容纳它。

确切值由编译器定义,可能因编译设置而异。