函数调用栈以及函数调用过程 for x86


Call 指令的实现

Near Call. When executing a near call, the processor pushes the value of the EIP register (which contains the offset 
of the instruction following the CALL instruction) on the stack (for use later as a return-instruction pointer). The 
processor then branches to the address in the current code segment specified by the target operand. The target 
operand specifies either an absolute offset in the code segment (an offset from the base of the code segment) or a 
relative offset (a signed displacement relative to the current value of the instruction pointer in the EIP register; this 
value points to the instruction following the CALL instruction). The CS register is not changed on near calls.



call func_b;
next_instruction;


when executing the instrution of "call func_b"
EIP = address of next_instruction;
let tempEIP = EIP;
let tempEIP = EIP + offset to func_b = address of func_b;


call func_b = two instructions
1: push current EIP (= next_instruction)
2: EIP = tempEIP (= address of func_b)



函数调用示例


stack of calling function

func_a()
{
func_b(x,y,z)
next_instruction;
}


func_a 完成
push z
push y
push x
call func_b == push  %EIP (= next_instruction)  
      mov   %EIP func_b


func_b 完成
push %ebp
mov  %ebp, %esp



对栈操作的语句 影响到的寄存器
func_a:
pushl z
pushl y
pushl x
pushl %EIP
movl %EIP next_instruction (following the call func_b);
funb_b:
pushl %EBP
movl %EBP %ESP

示意图1




示意图2



x86-64


  • %rax 作为函数返回值使用。
  • %rsp 栈指针寄存器,指向栈顶
  • %rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。
  • %rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防他被修改
  • %r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值