3、函数的本质 & 状态寄存器

2021-03-25  本文已影响0人  Jax_YD

2、函数调用栈的最后我们提到了<函数的参数和返回值>。我们讲到了:


总结:函数的参数,超出8个的部分存放在栈里面。比如从A函数进入B函数,B函数拥有超过8个的参数,则超出的部分放入A的函数调用栈中。

总结:当函数的返回值大于8个字节,x0存不下的时候。返回值会保存在上层函数的栈空间中。比如从A函数进入B函数,B函数的返回值超过8个字节,则返回值放入A的函数调用栈中。


状态寄存器

⚠️ 注:CPSR寄存器是32位的。

N(Negative)标志

指令执行后的结果 N的值
负数 N = 1
非负数(注意:非负数,包括0) N = 0

⚠️ 注意:在ARM64的指令集中,有的指令的执行是影响状态寄存器的,比如add/sub/or等(执行的时候要加s,如adds)。他们大都是运算指令(进行逻辑或算术运算)。


Z(Zero)标志

指令执行后的结果 Z的值 助记理解
结果为0 Z = 1 在计算机中1表示逻辑真,表示肯定;ZZero(0)的缩写;所以当结果为0的时候,Z = 1,表示结果是0
结果不为0 Z = 0 同上,Z = 0,表示结果不为0

C(Carry)标志

运算方式 运算结果 C的值 运算结果 C的值
加法运算 结果产生了进位(无符号数溢出) C = 1 没有产生进位(无符号数没有溢出) C = 0
减法运算(包括CMP) 结果产生了借位(无符号数溢出) C = 0 没有产生进位(无符号数没有溢出) C = 1

对于位数为N的无符号数来说,其对应的二进制信息的最高位,即第N-1位,就是它的最高有效位,而假想存在第N位,就是相对于最高有效位的更高位。如下图所示:


image.png
mov w0,#0xaaaaaaaa;0xa 的二进制是 1010
adds w0,w0,w0; 执行后 相当于 1010 << 1 进位1(无符号溢出) 所以C标记 为 1
adds w0,w0,w0; 执行后 相当于 0101 << 1 进位0(无符号没溢出) 所以C标记 为 0
adds w0,w0,w0; 重复上面操作
adds w0,w0,w0
mov w0,#0x0
subs w0,w0,#0xff ;
subs w0,w0,#0xff
subs w0,w0,#0xff

V(Overflow)溢出标志

计算 结果
正数 + 正数 结果为负数,溢出
负数 + 负数 结果为正数,溢出
正数 + 负数 不可能溢出

tips

⚠️ 注意:函数的局部变量是保存在栈里面的,所以当函数执行完毕,栈被销毁之后,函数的内的局部变量也会被销毁。所以外部函数无法访问函数内部的局部变量。

指令名 区别
ldr 用于正数(偏移值是正数)
ldp 操作两个寄存器
ldur 用于负数(偏移值是负数)
上一篇 下一篇

猜你喜欢

热点阅读