跳转至

7 章 函数⚓︎

348 个字 26 行代码 预计阅读时间 2 分钟

函数(function) 又称过程(procedure)。在 x86 中,根据调用和返回指令的不同,有近函数(过程)和远函数(过程)之分。一共有 2 种定义函数的方式:

  • 用标号定义函数
; 近函数定义1
标号名:
    ...
    retn  ; 可简写为 ret


; 近函数定义2
标号名 label near
    ...
    retn  ; 可简写为 ret

; 远函数定义
标号名 label far
    ...
    retf
  • proc定义函数
; 近函数定义
函数名 proc near
    ...
    retn    ; 可简写为 ret
函数名 endp

; 远函数定义
函数名 proc far
    ...
    retf
函数名 endp

函数传参的方式:

  • 用寄存器传参
    • 局限:寄存器数量较少,可能不够用
  • 用(全局)变量传参
    • 局限:当函数是一个递归函数时,函数多次自我调用会破坏变量中的参数值
  • 用堆栈传参,有以下几种规范:
    • __cdecl
      • 参数按从右到左的顺序压入堆栈
      • 参数的清理由调用者 (caller) 负责
      • 当函数值是整数时由 eax 返回,是小数时则由 st(0) 返回
      • eax、ecx、edx 由调用者负责保存和恢复
      • ebx、ebp、esi、edi 由被调用者 (callee) 负责保存和恢复
    • __pascal
      • 参数按从左到右的顺序压入堆栈
      • 参数的清理由被调用者负责
    • __stdcall
      • 参数按从右到左的顺序压入堆栈
      • 参数的清理由被调用者负责
    • 函数开头需要用push bpmov bp, sp这两条指令来构造堆栈框架(stack frame)
    • 构造好堆栈框架后,接着执行指令sub sp, idata就可以在函数内部定义宽度为idata动态变量或动态数组

递归⚓︎

评论区

如果大家有什么问题或想法,欢迎在下方留言~