跳转至

子程序设计

过程定义的伪操作:

procedure_name PROC NEAR(FAR)
    ...
procedure_name ENDP
- NEAR属性:调用程序和子程序在同一代码段中(段内调用) - FAR属性:调用程序和子程序不在同一代码段中(段外调用)

子程序的调用与返回

  • 子程序的调用:隐含使用堆栈保存返回地址
    • near:
      1. 保存返回地址:push ip
      2. 转到子程序中:ip<-目标子程序的地址
    • far:
      1. 保存返回地址:push cs; push ip
      2. 转到子程序中:cs<-目标子程序的段地址;ip<-目标子程序的偏移地址

程序与子程序之间的参数传递

  • 传参的方式:
    • 寄存器传参
      • 传输单个变量,适用于参数较少的情况
      • 通过传输指针来传递一个缓冲区
    • 内存单元传参:适用于传递全局变量的情况
    • 堆栈传参

主程序通过堆栈将参数传递到子程序

  • 假设传入参数为X

    • 传入参数的过程:
      1. PUSH X:传入参数
      2. PUSH CS:如果是FAR类型的过程,保存程序段
      3. PUSH IP:保存IP
    • 提取参数的过程:
      1. PUSH BP
      2. MOV BP, SP
      3. MOV AX, WORD PTR[BP + 4]:取出参数
        1. 如果为FAR类型,需要使用MOV AX, WORD PTR[BP + 6]
  • 假设传入参数为X,传出参数为Y

    • 传入参数的过程:
      1. SUB SP, 2
      2. PUSH X
      3. PUSH CS:FAR类型下调用
      4. PUSH IP
    • 子程序中的提取与返回:
      1. PUSH BP
      2. MOV BP, SP
      3. 取出数据:MOV AX, WORD PTR[BP + 4]
      4. 返回数据:MOV WORD PTR[BP + 6], AX
  • 参数的销毁:
    • 主程序:ADD SP, 2
    • 子程序:RET 2
  • 取出传回的值:POP AX

案例

C语言传入、传出参数约定

  • 返回值:通过寄存器返回
    • AL<-char
    • AX<-short
    • EAX<-int
    • (EDX, EAX)<-_int64
    • EAX<-指针
  • 传入参数:通过堆栈
    • 规则:由右向左,逐个放入堆栈