汇编栈(四)

栈:是一种具有特殊的访问方式的存储空间(后进先出, Last In Out Firt,LIFO)

1.SP和FP寄存器(push pop没了)

  • sp寄存器在任意时刻会保存我们栈顶的地址.
  • 现在是通过sp便宜来栈放数据
  • sp寄存器指向哪里,哪里就是栈

fp寄存器也称为x29寄存器属于通用寄存器,但是在某些时刻我们利用它保存栈底的地址!()

注意:上面sp上下拉的时候必须是16字节或16倍数。

注意:ARM64开始,取消32位的 LDM,STM,PUSH,POP指令! 取而代之的是ldr\ldp str\stp
ARM64里面 对栈的操作必须是16字节对齐的(也就是sp必须是16的倍数)!!

2.关于内存读写指令

注意:读/写 数据是都是往高地址读/写

str(store register)指令

将数据从寄存器中读出来,存到内存中.

ldr(load register)指令

将数据从内存中读出来,存到寄存器中

此ldr 和 str 的变种ldp 和 stp 还可以操作2个寄存器.

例子:

使用32个字节空间作为这段程序的栈空间,然后利用栈将x0和x1的值进行交换.

上面是把寄存器放到栈中(control+鼠标左键进入汇编代码,把x0,x1赋值 0xffffffff,register write x0 0xffffffff: 往寄存器x0赋值)

stp 如果是减 stp x0,x1,[sp,#-0x10]

add sp,sp,#0x20: 是为了栈平衡(出函数后里面局部变量等这些都不要了)


问题:

1. sp根据什么决定拉伸多少空间?

根据参数和变量size和函数调用来开辟多少空间,比如下面例子,如果没有参数f,那么他就是-> 0x100bac704 <+0>: sub sp, sp, #0x10 ; =0x10, 开辟的是0x10也就是16字节(sizeof(int)*4),如果是5个int参数sizeof(int)*5超过了栈地址对齐16字节,它就直接开辟0x20也就是32字节

如果在sumA增加一个函数调用

寄存器会把x30的值入栈,保存这个函数的值 这时也会开辟栈空间又增加了16字节(0x20+0x10)(其实arm中包含x29和x30都会进栈+0x20 看下面代码)

发表回复

电子邮件地址不会被公开。 必填项已用*标注

Protected with IP Blacklist CloudIP Blacklist Cloud