本文章是小编根据在学习时做的总结笔记。涉及到sp,str,ldr,sp寄存器
栈:是一种具有特殊的访问方式的存储空间(后进先出, Last In Out Firt,LIFO)
堆栈操作练习代码如下:
.text
.global _A
_A:
sub sp,sp,#0x20
stp x0,x1,[sp ,#0x10]
ldp x1,x0,[sp ,#0x10]
add sp,sp,#0x20
ret
关于内存读写指令
*注意:读/写 数据是都是往高地址读/写
str(store register)指令
将数据从寄存器中读出来,存到内存中.
ldr(load register)指令
将数据从内存中读出来,存到寄存器中
此ldr 和 str 的变种ldp 和 stp 还可以操作2个寄存器.
SP和FP寄存器:
sp寄存器在任意时刻会保存我们栈顶的地址.
fp寄存器也称为x29寄存器属于通用寄存器,但是在某些时刻我们利用它保存栈底的地址!()
注意:ARM64开始,取消32位的 LDM,STM,PUSH,POP指令! 取而代之的是ldr\ldp str\stp
ARM64里面 对栈的操作是16字节对齐的!!
//sub sp,sp,#0x20
sp指向c0
c0往上走32个字节,就是走2个16字节。
c0地址 往上走 #0x20 。(c0-20=a0 也就是0x000000016aeab9a0)
蓝色为拉伸空间,sub往高地址写
从9ao开始写入两个64位寄存器。每个64位寄存器占8个字节。那么,两个寄存器-存进去-正好是16个字节
我们发现并没有从sp开始存,而是从sp + #x10开始存。因为代码是[sp ,#0x 10]是从这里开始存的。
// add sp,sp,#0x20
接下来,我们读。ni一下。刚才我们是把寄存器放到栈空间里去,但是注意细节是我们有add,这样的目的是,如果不add就会导致内存不够用。内存泄露一般是指堆区域的对象被创建出来,不释放,但是栈空间的代码是编译器写好的,所以如果不做这样的事情,这个函数被调用多次,我们的栈空间就会一直往上走。(每次都往高地址走,每次都减,调多了就麻烦啦)所以这个函数被调用完,局部的变量,我们不用了,就add。达到栈平衡。