每日一课(6/75) 子程序的定义 调用及返回

 

1. 子程序的定义
如同C语言一样,汇编语言也具备结构化的能力。
首先说子程序的定义格式:

子程序名 PROC [NEAR | FAR] 
… ;子程序体 
子程序名 ENDP 

PROC和ENDP是子程序的首尾标识,子程序名必须是相同的,子程序可以分为NEAR近调用和FAR远调用,所谓近调用就是只能在同一段内的其他程序调用,而远待用可以被不同段的程序调用。

2. 子程序的调用
所以,根据NEAR和FAR,也有相应的调用方式,NEAR的子程序调用的时候只需要把偏移量压栈即可,FAR的子程序要把段地址和偏移量压栈(分别压入CS和IP寄存器),然后即可调用。

调用的方式:

CALL  DISPLAY

;DISPLAY是子程序名

CALL  BX

;BX的内容是子程序的偏移量

CALL  WORD1

;WORD1是内存字变量,其值是子程序的偏移量

CALL  DWORD1

;DWORD1是双字变量,其值是子程序的偏移量和段值

CALL  word ptr [BX]

;BX所指内存字单元的值是子程序的偏移量

CALL  dword ptr [BX]

;BX所指内存双字单元的值是子程序的偏移量和段值

3. 子程序的返回
当子程序执行完了之后,需要返回到主调指令上下文中,并不像跳转指令那样不会返回,为了实现这个功能,指令系统提供了一条专用指令RET.
RET/RETN/RETF [imm]
子程序的返回在功能上来说是子程序的调用的逆操作,为了与子程序的远/近调用相对应,子程序的返回也分为远返回和近返回。
返回指令在堆栈方面是调用指令的逆操作。

在近类型的子程序中,返回指令RET是近返回,功能是把栈顶的值弹出到指令指针寄存器IP中,SP会被加2。

在远类型的子程序中,返回指令RET是远返回,功能是:先弹出栈顶的值到IP中,再弹出栈顶的值到CS中,SP总共向后移动了4位(当然80386+的CPU是ESP向后移动了两个四位)

如果返回指令后面加入了立即数,那么表示返回地址之后,SP还要增加的偏移量。并不是高级语言中return的值。

在masm5.0+的环境中可以直接使用RETN和RETF来显示告诉编译器本子程序是近返回还是远返回。

RET

;可能是近返回,也可能是远返回

RETN

;近返回指令

RETF

;远返回指令

RET 6

;子程序返回后,(SP)←(SP) + 6

你可能感兴趣的:(程序)