标准的子程序结构
利用跳转可以实现子程序调用。所谓调用,实际上就是程序转移到该标号去继续执行。。这种方式虽然简便,但是在模块化程序结构设计中,是不规范的。尤其是其它模块中的某个程序想要调用这个子程序时,还需要指明该子程序标号是在哪个模块、哪个代码段的哪个程序中。
标准的用法是用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
来源:oschina
链接:https://my.oschina.net/u/4324171/blog/3556078