子程序
结构
有参
CALL时,会把断点下一条指令的地址放入堆栈,段内调用,只需要保存偏移地址即可;段间调用,要多放段基址在堆栈。
RET时,会取出这些,然后装到CS IP指针里头。
有参:
- 通过寄存器
MOV DX,OFFSET MESG
CALL DIAP
DISP PROC
MOV AH,9
INT 21H
RET
DISP ENDP
- 利用堆栈区
- 利用内存单元
无参
无参:
CRLF PROC
MOV AH,2
MOV DL,0DH
INT 21H
MOV AH,2
MOV DL,0AH
INT 21H
RET
CRLF ENDP
宏
无参
无参宏指令
先定义后调用,
定义可以不放在任何逻辑段中,习惯放在源程序首部。
汇编时,汇编程序自动用宏体取代宏调用。
.586
CRLF MACRO
MOV AH,0EH
MOV AL,0DH
INT 10H
MOV AL,0AH
INT 10H
ENDM
CODE SEGMENT USE16
ASSUME CS:CODE
BEG:MOV AH,2
MOV DL,'A'
INT 21H
CRLF
有参
有参宏指令
实元表:一串用逗号(或空格)间隔的立即数,寄存器操作数或没有PTR的存储器操作数。
汇编时,汇编程序自动地把实元一一对应赋给哑元。
!!!在宏里面出现了标号:LOCAL 用逗号间隔的标号名 (说明是局部标号)
异同
宏和子程序的异同:
相同点:简化程序设计。
不同点:
- 调用发生的时刻不同:宏在程序汇编时刻发生,子程序在程序运行时刻发生,宏对目标程序的尺寸减小无任何贡献,而子程序有。
- 调用需要的时间不同:宏是替换操作,时间相对短,子程序是 程序控制流转移过程,并且用堆栈保存断点地址,需要时间相对长。
- 调用的方式和参数传递方式不同:宏用名称,子程序用CALL以及RET。宏用形参和实参,子程序用寄存器,堆栈,内存单元,
代码
.586
CRLF MACRO ;换行回车功能
MOV AH,0EH
MOV AL,0DH
INT 10H
MOV AL,0AH
INT 10H
ENDM
DISP MACRO VAR,NN
LOCAL L1,L2
MOV CH,NN/4
L1: MOV CL,4
L2: MOV AL,'0'
ROL VAR,1
ADC AL,0 ;ADC指令:操作对象1+操作对象2+CF
MOV AH,0EH
INT 10H
DEC CL
JNZ L2
MOV AL,' '
INT 10H
DEC CH
JNZ L1
CRLF
ENDM
CODE SEGMENT USE16
ASSUME CS:CODE
NUM DB 88H
BEG:MOV EBX,12345678H
DISP BH,8
DISP BX,16
DISP EBX,32
DISP NUM,8
MOV AH,4CH
INT 21H
CODE ENDS
END BEG