汇编学习(二)

1、内存


内存是分区域的:

代码区 : 可读可写可执行
栈区 :存放参数和局部变量 可读可写 动态申请
堆区:可读可写 动态申请
全局变量区:可读可写
常量区:只读

栈和堆

栈是一种具有特殊访问方式的存储空间,先进后出;(和堆相反,堆是先进先出
对栈的操作要保持栈平衡

  • 栈是从高地址向低地址方向拉伸;(堆空间是从低地址向高地址拉伸
  • 读写是从低地址向高地址方向
SP和FP寄存器
  • SP寄存器在时候执行栈顶的位置。
  • FP寄存器也是x29寄存器,属于通用寄存器,某些时刻用来保存栈底的位置。

需要注意:ARM64开始,取消了32位的LDM,STM,PUSH,POP的指令!取而代之是ldr/ldp/str/stp
ARM64里面对栈的操作,是16字节对齐的!

X30寄存器
X30寄存器存放的是函数的返回地址,当ret指令执行的时候,会寻找x30寄存器保存的地址值

状态寄存器(cpsr)

cpsr 的低八位是控制位
cpsr 是32位寄存器 最高位的4个bit位,每个bit位的1都有不同的意义

高四位分别是 N 、Z、C 、V 条件标志位。他们的内容可被算术或逻辑运算的结果改变。并且可以判断某条指令是否被执行过!!!

N(Negative)标志位
cpsr的31位是N 符号标志位,他记录相关指令执行后,其结果是否为负数,若是负数,则 N = 1,否则 N = 0

注意,在ARM64的指令集中,有的指令的执行时影响状态寄存器的,比如add\sub\or等,他们大都是运算指令(进行逻辑或算数运算);
adds subs 有符号运算

Z(Zero)标志位
cpsr的30位是Z 0标志位,他记录相关指令执行后,其运算结果是否为0,若结果是0,则 Z = 1,否则 Z = 0
C(Carry)标志位
cpsr的29位是C 进位标志位。一般情况下进行无符号运算。
加法运算:当运算结果产生了进位时候(无符号溢出),则 C = 1,否者C = 0。
减法运算:当运算时产生了借位时(无符号数溢出),C = 0,否则 C = 1 。
V(Overflow)溢出标志

cpsr的28位 V,溢出标志位,在进行有符号数运算时候,如果超过了机器所能识别的范围,称之为溢出。则,V = 1,否则 V = 0。


bl指令

bl指令的作用

  • 将下一条指令的地址放入到x30(lr)寄存器
  • 跳转到标号处指令指令
ret指令
  • 默认使用lr(X30)寄存器中的值,通过底层指令提示CPU此处作为下条指令地址!
  • 注意:在函数嵌套调用的时候,需要先将x30入栈
因为函数嵌套会有多个bl指令 ,而bl指令处 要先把下条指令地址保存到x30寄存器 ,这样就会覆盖,因此要先入栈保存。
adrp指令
例如:adrp x0 ,1    ==> 有个作用
    1、将1的值<<(左移)12位 0x1000
    2、将pc寄存器的低12位清零 0x1002e6789==>0x1002e6000
    3、将pc低12位清零后的值 加上 第一步的结果 给 x0寄存器
    
adrp是计算制定的数据地址 到当前pc值的相对偏移
由于得到的结果是低12bit位是0 4kb的大小 常量就在这偏移的4kb范围内

2、函数的参数和返回值


在ARM64下,函数的参数是放在x0-x7(w0-w7)这个8个寄存器中的,如果超过了8个参数的话,函数就会入栈。
函数的返回值会存放在x0中

函数的局部变量是放在栈中的。因为出了这个函数区域,局部变量就不能再被使用被销毁了。

你可能感兴趣的:(汇编学习(二))