跳转到内容

call & stack

stack有两个动作,push放入栈,pop取出

push rax

rsp寄存器永远指着栈顶部 push image

  1. 将rsp减少
  2. 将内容从新的rsp开始放入

类似代码:

sub rsp, 8
mov [rsp], rax

在C/C++的编译风格,每次进入函数开始前会像上图一样分配一块适当大小的空间
rbp指向局部变量的顶端
push rbp 将原先的rbp保存起来,然后把rbp设为当前rsp,再把rsp减去要分配的空间大小
以上图来说明就是 rbp = rsp, rsp -= 0x8
在函数结束的最后做相反的动作把rsp加回来再 pop rbp 还原rbp成上一个地方的局部变量顶端地址
自己编写assembly不一定要使用C/C++的局部变量风格

pop rbx

pop image

pop的动作跟push相反

  1. 将rsp内容取出
  2. 将rsp增加

类似代码:

mov [rsp], rbx
add rsp, 8

使用 call label 呼叫函数,和 jmp label 非常相似,差别是call结束会返回原本的下一行
call前我们需要手动将参数依序放入固定位置,rdi, rsi, rdx, rcx, r8, r9, push… 然后使用call
指令call可以拆分成以下两个动作

push rip
jmp label

将永远指向下一行指令位址的rip推入栈,然后jmp

接着执行完内容使用ret返回到原本的下一行继续执行,若有返回值请手动存入rax再做ret
ret一样可以拆分为下列动作

pop rip

将之前的rip从栈取出并放入rip,程式会依照rip所指的地方执行