汇编看函数栈

堆栈

栈在计算机中就是一块连续的存储区域(至少虚拟地址是连续的),在这块连续的存储区域写入和删除数据依据先进后出的规则进行

栈空间由系统自动分配自动释放,我们经常在函数内部创建的局部变量等数据是存放在栈帧中

在虚拟地址上是连续的 在物理内存是分散的(本文讨论都是在虚拟内存上)

栈的生命周期

1、Kernel创建用户栈,为栈分配内存空间,用户栈的建立是伴随着可执行文件的加载建立的。

栈其实分为内核栈 和用户栈 内核栈不在讨论范围内

2、运行到用户程序的main函数,main()函数内部调用其它子函数,子函数在调用其他函数 让我们的程序运行连贯起来。 每次函数的调用其实就是切换栈帧

3、mian()函数返回,整个进程结束,释放栈占的内存,栈消失。

函数栈

下图是x86-64的函数栈的结构, 函数P调用函数Q的过程,Q正在执行

请添加图片描述

在ARM上

以一段oc代码为例

- (void)test1 {
    
    
    int a = 1;
}

转cpp代码

static void _I_ViewController_test1(ViewController * self, SEL _cmd) {
    
    
    int a = 1;
    NSLog((NSString *)&__NSConstantStringImpl__var_folders_zm_558cwfjs099fbm2r8kxg8wt00000gt_T_ViewController_21e9d9_mi_0,&a);
}

对应汇编

指针偏移`-[ViewController test1]:
   1 0x1028bda10 <+0>:  sub    sp, sp, #0x20             ; =0x20 
   2 0x1028bda14 <+4>:  str    x0, [sp, #0x18]
   3 0x1028bda18 <+8>:  str    x1, [sp, #0x10]
   4 0x1028bda1c <+12>: mov    w8, #0x1
   5 0x1028bda20 <+16>: str    w8, [sp, #0xc]
-> 6 0x1028bda24 <+20>: add    sp, sp, #0x20             ; =0x20 
   7 0x1028bda28 <+24>: ret  

ARM汇编分析
1. sp容器展开 32个字节大小
2. x0 对应self的地址 存放 sp+0x18 位置
3. x1 对应cmd的地址 存放 sp+0x10 位置
4. 1 赋值给w8 寄存器 (x8的低32位就是w8寄存器)
5. w8 寄存器的值 存放到 sp+0xc的位置
6. 回收sp容器
7. 释放 test1函数栈空间

图示
请添加图片描述

上面的黑黄红3小块 也就是 12个字节 是为了栈对齐开辟的 栈要求16字节对齐 所以我们发现栈指针的地址 都是16的倍数,栈对齐能让cpu的寄存器尽可能少的内存访问周期内读取数据。

Supongo que te gusta

Origin blog.csdn.net/u014641631/article/details/121408859
Recomendado
Clasificación