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

来源:互联网 发布:淘宝关注店铺送优惠券 编辑:程序博客网 时间:2024/06/05 17:45


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
原创粉丝点击