函数调用原理
CALL指令
call指令完成的功能类似于以下操作:
push esp: 将当前指令地址压栈作为函数的返回地址jmp [address]: 跳转到函数所在地址进行调用
注: 如果函数有参数的话会先按照从右向左的顺序将参数压栈
函数结构
push ebp
mov esp, ebp
; 寄存器压栈
; 逻辑
; 寄存器弹栈
leave
ret
保留现场: 创建栈帧
在创建新的栈帧之前需要先把原来栈底的地址保存,以便于调用返回时恢复到原来的栈帧
push ebp
mov esp, ebp
恢复现场: 调用返回
- 恢复到原来的栈帧
- 跳转到返回地址
leave
ret
向内核传递参数
.text
.global _start
.extern csos_init
_start:
push %ebp
mov %esp, %ebp
mov 0xC(%ebp), %eax
push %eax
mov 0x8(%ebp), %eax
push %eax
call csos_init
jmp .