汇编语言

汇编四 — 内存分区

2018-06-27  本文已影响0人  Superman168

内存分区

特点:动态申请 可读可写

特点:由系统进行内存的管理。主要存放函数的参数以及局部变量。
在函数完成执行,系统自行释放栈区内存,不需要用户管理。

存放程序的二进制代码。比如我们写的函数,都是在代码区的。特点: 可读可写可执行,存放程序编译后的二进制代码,不可寻址区。

特点:可读可写
静态存储区内的变量在程序编译阶段已经分配好内存空间并初始化。这块内存在程序的整个运行期间都存在,它主要存放静态变量、全局变量和常量。
包括:常量区(静态常量区),全局区(全局变量区)和静态变量区(静态区)。

特点: 只读!
字符串常量区和常变量区。

计算机寻找原理

如以下的函数:

int f = 10;

int func (int a, int b){
    printf("hahha");
    
    int c = a + f;
    
    return c;
}

int main(int argc, char * argv[]) {
    
    printf("%d",func(1, 2));
    
    return 0;
}

寻找常量和全局变量:

image.png

注意上面的 adrp 指令 (adrp:address page 常量)

adrp x0, 1
1. 将1的值,左移12位 1 0000 0000 0000 == 0x1000
2.将PC寄存器的低12位清零 pc = 0x0000000100fe2874; 0x100fe2874 ==> 0x100fe2000
3.将将1 和 2 的结果相加 给 X0 寄存器!!

adrp 是计算指定的数据地址 到当前PC值的相对偏移;
由于得到的结果是低12bit为0,
2^10 == 1024 Byte
2^12 == 4KB
所以要寻找的地址和当前 pc 的值的误差即4 kb, 也就是要寻找的(常量所在的)地址一定会在这 4KB 里面。现在找到的是一个粗略的基址,以这个基址可以在(再加上)偏移4 kb 的范围内找到。

要算准确的地址呢?

第二句:add x0, x0, #0xf28 中的偏移 #0xf28,计算机编译的时候知道的偏移地址,和此时的 pc 为:

Printing description of $pc:
(unsigned long) pc = 0x0000000100fe2888
可以得到:
0x100fe2888—> 0x100fe3000—>0x100fe3f28
计算过程:
p (char *) 0x100fe2000 + 0x1000 + 0xf28 = 0x100fe3f28

可以看到结果如下:

常量

第二个 adrp (全局变量)

此时的 (unsigned long) pc = 0x0000000100fe2894
通过推算,准确的地址为:0x0000000100fe4d10

打印结果如下:

image.png

可以看到,找到的则为全局变量 f 的值。

注意:需要说明的一点是:要打印地址的值,即为指针做指向的值,p (Int *) 打印的还是这个地址,要打印该地址的值则为:p *(int *) + 地址。

上一篇 下一篇

猜你喜欢

热点阅读