题目:
      . 已知array1字数组中存放着n个无符号数。编写子程序,分别求这n个数的平均值、最大值、最小值,并输出这n个数以及所求结果
 
子程序设计
分析:
     定义数据段,保存数据数组、保存数据长度、平均值、最大值、最小值;每次调用函数获得值时保存在对应的变量里面,就类似与高级语言设计中的全局变量
源代码
  1 .386
  2 data segment use16
  3   masg0 db 0ah, 0dh, '=====output singned numbers======',0dh,0ah,'$'
  4   masg1 db 'numbers are:  $'
  5   masg2 db 0ah, 0dh, 'average of the numbers is:  $'
  6   masg3 db 0ah, 0dh, 'maximum of the numbers is:  $'
  7   masg4 db 0ah, 0dh, 'minimum of the numbers is:  $'
  8   array1 dw   12, 2, 3, 5, 6, 7, 32767  
  9   nums   equ ($-array1)/2
 10   max    dw ?
 11   min    dw ?
 12   avg    dw ?
 13 data ends
 14 
 15 stack segment use16 stack
 16   db 200 dup(0)
 17 stack ends
 18 
 19 code segment use16
 20   assume cs:code, ds: data, ss: stack
 21 start:
 22   ;初始化
 23   mov ax, data
 24   mov ds, ax
 25   mov ax, stack
 26   mov ss, ax
 27   
 28   ; 输出提示
 29   lea dx, masg0
 30   mov ah, 9
 31   int 21h
 32   
 33   lea dx, masg1
 34   mov ah, 9
 35   int 21h
 36   
 37   ;显示数字
 38   mov cx, nums;
 39 show:
 40   mov si, cx
 41   dec si
 42   add si, si
 43   mov ax, array1[si]
 44   call shownumber
 45   loop show
 46   
 47   ; 输出提示
 48   lea dx, masg2
 49   mov ah, 9
 50   int 21h
 51   ;计算平均值
 52   call countaverage
 53   mov ax, avg
 54   call shownumber
 55   
 56   ; 输出提示
 57   lea dx, masg3
 58   mov ah, 9
 59   int 21h
 60   ;计算最大值
 61   call countmax
 62   mov ax, max
 63   call shownumber
 64   
 65   ; 输出提示
 66   lea dx, masg4
 67   mov ah, 9
 68   int 21h
 69   ;计算最小值
 70   call countmin
 71   mov ax, min
 72   call shownumber
 73   
 74   ;退出
 75   call exit
 76   
 77   ;以十进制输出一个无符号字元素
 78   ; 数据在ax中
 79 shownumber  proc near
 80   pusha           ;保存现场,
 81   mov cx, 0
 82   countbit:       ;一位位处理
 83     mov dx, 0
 84     mov bx, 10
 85     div bx  ;除10
 86     push dx ;保存余数
 87     inc cx  ;位数目加一
 88     cmp ax, 0
 89     ja countbit  ;商不为零跳转
 90   ;显示
 91   showbit:
 92     pop dx
 93     add dl, 30h
 94     mov ah, 2
 95     int 21h
 96     loop showbit ;大于零,还有位未处理跳转
 97   ;显示空格
 98   mov dl, 20h
 99   mov ah, 2
100   int 21h
101  
102   popa        ;恢复现场
103   ret         ;返回
104 shownumber  endp
105 
106   ;计算平均值
107   ;使用全局的数组,和数组长度
108   ;把平均值保存到变量avg中
109 countaverage proc near 
110   pusha   ;保存现场
111   mov cx, nums
112   mov ax, 0
113 addnum:  
114   mov si, cx
115   dec si
116   add si, si
117   mov bx, array1[si]
118   add ax, bx
119   loop addnum
120   
121   mov dx, 0
122   mov bx, nums
123   div bx
124   
125   mov avg, ax
126   popa    ;恢复现场
127   ret     ;返回
128 countaverage endp
129 
130   ;计算最大值
131   ;使用全局变量array1,和数组长度nums
132   ;最大值保存到max 
133 countmax  proc near
134   pusha   ;保存现场
135   mov cx, nums
136   mov ax, 0
137 next1:
138   mov si, cx
139   dec si
140   add si, si
141   mov bx, array1[si]
142   cmp bx, ax
143   jna low1
144   mov ax, bx
145 low1:
146   loop next1
147   
148   mov max, ax
149   popa    ;恢复现场
150   ret     ;返回
151 countmax  endp
152 
153   ;计算最小值
154   ;使用全局变量
155   ;最小值保存到min中
156 countmin  proc near
157   pusha   ;保存现场
158   
159   mov cx, nums
160   mov si, cx
161   dec si
162   add si, si
163   mov ax, array1[si] 
164   dec cx
165   
166 next2:
167   mov si, cx
168   dec si
169   add si, si
170   mov bx, array1[si]
171   cmp bx, ax
172   ja high1
173   mov ax, bx
174 high1:
175   loop next2
176   
177   mov min, ax
178   popa    ;恢复现场
179   ret     ;返回
180 countmin  endp
181   
182   ;退出
183 exit  proc
184   mov ah, 4ch
185   int 21h
186 exit endp
187   
188 code ends
189      end start子模块设计
分析
需要了解一下子模块的设计的一些规则,如name,extern,public,高级语言的多文件编译可以在汇编语言中找到实现的最明显的启示;用模块化编程实现,将主程序放在一个模块中;将平均值、最大值、最小值函数放在一个模块中;将显示输出放在另一个模块中。
源代码
主函数:
 1       name main
 2       extrn countaverage: near, countmax: near, countmin: near, shownumber: near
 3       public array1, nums, number, avg, min, max
 4 .386
 5 data segment use16 para public 'datas'
 6   masg0 db 0ah, 0dh, '=====output singned numbers======',0dh,0ah,'$'
 7   masg1 db 'numbers are:  $'
 8   masg2 db 0ah, 0dh, 'average of the numbers is:  $'
 9   masg3 db 0ah, 0dh, 'maximum of the numbers is:  $'
10   masg4 db 0ah, 0dh, 'minimum of the numbers is:  $'
11   array1 dw   1, 2, 3, 5, 6, 7  
12   nums   dw  6
13   number dw ?
14   max    dw ?
15   min    dw ?
16   avg    dw ?
17 data ends
18 
19 stack segment use16 para stack 'stack'
20   db 200 dup(0)
21 stack ends
22 
23 code segment use16 para public 'code'
24   assume cs:code, ds: data, ss: stack
25 start:
26 ;初始化
27   mov ax, data
28   mov ds, ax
29   mov ax, stack
30   mov ss, ax
31   
32   ; 输出提示
33   lea dx, masg0
34   mov ah, 9
35   int 21h
36   
37   lea dx, masg1
38   mov ah, 9
39   int 21h
40   
41   ;显示数字
42   mov cx, nums;
43 show:
44   mov si, cx
45   dec si
46   add si, si
47   mov ax, array1[si]
48   mov number, ax
49   call shownumber
50   loop show
51   
52   ; 输出提示
53   lea dx, masg2
54   mov ah, 9
55   int 21h
56   ;计算平均值
57   mov dx, ds
58   call countaverage
59   mov ax,  avg
60   mov number, ax
61   call shownumber
62   
63   ; 输出提示
64   lea dx, masg3
65   mov ah, 9
66   int 21h
67   ;计算最大值
68   mov dx, ds
69   call countmax
70   mov ax,  max
71   mov number, ax
72   call shownumber
73   
74   ; 输出提示
75   lea dx, masg4
76   mov ah, 9
77   int 21h
78   ;计算最小值
79   mov dx, ds
80   call countmin
81   mov ax,  min
82   mov number, ax
83   call shownumber
84   ;退出
85   mov ah, 4ch
86   int 21h
8788     end start
计算函数:
 1       name count
 2       extrn nums: word, array1: word, avg:word, min: word, max:word
 3       public countaverage, countmax,  countmin
 4 .386
 5 data segment use16 para public 'datas'
 6 data ends
 7 
 8 stack segment use16 para stack 'stack'
 9   db 200 dup(0)
10 stack ends
11 
12 code segment use16 para public 'code'
13   assume cs:code, ds:data, ss: stack
14    ;初始化
15   mov dx, data
16   mov ds, dx
17   mov dx, stack
18   mov ss, dx
19    
20  
21   ;计算平均值
22   ;数据保存在ds段中
23   ;把平均值保存到变量avg中
24 countaverage proc near
25   pusha   ;保存现场
26   mov ds, dx
27   mov cx, nums
28   mov ax, 0
29 addnum:  
30   mov si, cx
31   dec si
32   add si, si
33   mov bx, array1[si]
34   add ax, bx
35   loop addnum
36   
37   mov dx, 0
38   mov bx, nums
39   div bx
40   
41   mov avg, ax
42   popa    ;恢复现场
43   ret     ;返回
44 countaverage endp
45 
46   ;计算最大值
47   ;数据保存在ds中,和数组长度nums
48   ;最大值保存到max 
49 countmax  proc near
50   pusha           ;保存现场,
51   mov ds, dx
52   mov cx, ds:nums
53   mov ax, 0
54 next1:
55   mov si, cx
56   dec si
57   add si, si
58   mov bx, ds:array1[si]
59   cmp bx, ax
60   jna low1
61   mov ax, bx
62 low1:
63   loop next1
64   
65   mov ds:max, ax
66   popa        ;恢复现场
67   ret     ;返回
68 countmax  endp
69 
70   ;计算最小值
71   ;数据保存在ds中
72   ;最小值保存到min中
73 countmin  proc near  
74   pusha           ;保存现场,
75   mov ds, dx
76   mov cx, ds:nums
77   mov si, cx
78   dec si
79   add si, si
80   mov ax, ds:array1[si] 
81   dec cx
82   
83 next2:
84   mov si, cx
85   dec si
86   add si, si
87   mov bx,   ds:array1[si]
88   cmp bx, ax
89   ja high1
90   mov ax, bx
91 high1:
92   loop next2
93   
94   mov ds:min, ax
95   popa        ;恢复现场
96   ret     ;返回
97 countmin  endp
98 code ends
99     end 显示函数: 
 1       name show
 2       extrn number:word
 3       public shownumber
 4  ;以十进制显示number中的数据
 5 .386
 6 data segment use16 para public 'datas'
 7 data ends
 8 
 9 stack segment use16 para stack 'stack'
10   db 200 dup(0)
11 stack ends
12 
13 code segment use16 para public 'code'
14   assume cs:code, ds: data, ss: stack
15   ;初始化
16   mov dx, data
17   mov ds, dx
18   mov dx, stack
19   mov ss, dx
20   
21  ;以十进制输出一个无符号字元素
22   ; 数据在ax中
23 shownumber  proc near
24   pusha           ;保存现场,
25   mov ax, number
26   mov cx, 0
27   countbit:       ;一位位处理
28     mov dx, 0
29     mov bx, 10
30     div bx  ;除10
31     push dx ;保存余数
32     inc cx  ;位数目加一
33     cmp ax, 0
34     ja countbit  ;商不为零跳转
35   ;显示
36   showbit:
37     pop dx
38     add dl, 30h
39     mov ah, 2
40     int 21h
41     loop showbit ;大于零,还有位未处理跳转
42   ;显示空格
43   mov dl, 20h
44   mov ah, 2
45   int 21h
46   popa        ;恢复现场
47   ret         ;返回
48 shownumber  endp      
49 code ends
50   end