美文网首页
第三章 iOS函数的本质 - 002 -(2)- [栈]

第三章 iOS函数的本质 - 002 -(2)- [栈]

作者: 我静静仰望着天空 | 来源:发表于2018-05-08 10:17 被阅读211次

    本文章是小编根据在学习时做的总结笔记。涉及到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个字节

    为了方便调试,改一下寄存器。写入0xffffffff

    我们发现并没有从sp开始存,而是从sp + #x10开始存。因为代码是[sp ,#0x 10]是从这里开始存的。

    此时sp指向0x000000016aeab9a0地址

    // add sp,sp,#0x20

    接下来,我们读。ni一下。刚才我们是把寄存器放到栈空间里去,但是注意细节是我们有add,这样的目的是,如果不add就会导致内存不够用。内存泄露一般是指堆区域的对象被创建出来,不释放,但是栈空间的代码是编译器写好的,所以如果不做这样的事情,这个函数被调用多次,我们的栈空间就会一直往上走。(每次都往高地址走,每次都减,调多了就麻烦啦)所以这个函数被调用完,局部的变量,我们不用了,就add。达到栈平衡。

    相关文章

      网友评论

          本文标题:第三章 iOS函数的本质 - 002 -(2)- [栈]

          本文链接:https://www.haomeiwen.com/subject/vwzefftx.html