标准的子程序结构
利用跳转可以实现子程序调用。所谓调用,实际上就是程序转移到该标号去继续执行。。这种方式虽然简便,但是在模块化程序结构设计中,是不规范的。尤其是其它模块中的某个程序想要调用这个子程序时,还需要指明该子程序标号是在哪个模块、哪个代码段的哪个程序中。
标准的用法是用8086汇编语言提供的过程定义伪指令PROC来定义子程序。
示例 从键盘键入一个多位十进制数X,回车结束输入。按十进制位相加后显示十进制结果Y。
设计思路:
(1) 主程序分别调用三个子程序。
(2) 子程序SUBR1为键盘输入多位十进制数且直接保存到X,输入的位数在BX;
(3) 子程序SUBR2将保存的X去掉ASCII码,按位相加,相加的结果在BX中;
(4) 子程序SUBR3将BX中的数用十进制显示;
(5) 采用将结果除以10保存余数的方法将BX中的数转换为十进制数,并用十进制数的ASCII码显示结果。
(6) 传参寄存器为BX。
代码:
1 ;a.asm 键入一个十进制数x,按位相加后显示十进制结果y。 2 data segment 3 infor1 db 0ah,0dh,'x=$' 4 infor2 db 0ah,0dh,'y=$' 5 x db 20 dup(?) 6 data ends 7 code segment 8 assume cs:code,ds:data 9 start: mov ax,data 10 mov ds,ax 11 ;主程序 12 main proc far ;主程序定义,远程的 13 mov x,0 14 mov dx,offset infor1 ;显示提示1 15 mov ah,9 16 int 21h 17 mov bx,0 ;传参寄存器bx清0 18 call subr1 ;调子程序1 19 mov cx,bx ;保存x的位数 20 mov ax,0 21 mov bx,0 22 call subr2 ;调子程序2 23 mov dx,offset infor2 ;显示提示2 24 mov ah,9 25 int 21h 26 call subr3 ;调子程序3 27 jmp main 28 out1: mov ah,4ch 29 int 21h 30 main endp 31 ;子程序1:键盘输入、保存 32 subr1 proc near ;定义子程序1,近程的 33 mov ah,1 ;键盘输入十进制数 34 int 21h 35 cmp al,0dh ;回车? 36 jz exit 37 cmp al,'0' ;其它非法字符? 38 jl out1 ;是转out1,直接退出 39 cmp al,'9' 40 jg out1 41 mov x[bx],al ;保存键入的数码 42 inc bx ;BX=数码个数 43 jmp subr1 44 exit: cmp bx,0 ;第一键就是回车 45 jz out1 46 ret ;返回主程序 47 subr1 endp 48 ;子程序2,按位相加 49 subr2 proc near ;定义子程序2,近程的 50 mov ah,x[bx] ;取出键入的数码 51 and ah,0fh ;去掉ASCII码 52 add al,ah ;按位相加 53 inc bx 54 loop subr2 ;循环累加 55 mov ah,0 56 mov bx,ax ;相加结果→bx传参寄存器 57 ret ;返回主程序 58 subr2 endp 59 ;子程序3,将bx中的数显示为十进制数 60 subr3 proc near ;定义子程序3,近程的 61 mov ax,bx ;bx为传参寄存器 62 mov cx,0 63 mov bx,10 64 let1: ;将ax变为十进制数 65 mov dx,0 ;字除法的高字清0 66 inc cx ;统计余数个数 67 div bx ;除以10,商在AX,余数在DX 68 push dx ;保存余数 69 cmp ax,0 70 jnz let1 71 let2: ;循环显示余数,循环次数在cx中 72 pop ax ;将余数弹入ax 73 add ax,0030h ;调整为ASCII码 74 mov dl,al ;2号功能显示 75 mov ah,2 76 int 21h 77 loop let2 78 ret ;返回主程序 79 subr3 endp 80 code ends 81 end start