该课程设计是在屏幕输出公司21年的详细信息,包括年份、当年总收入、当年人数、当年的人均收入(这个需要运用除法运算)。
显示总收入需要解决除法溢出的问题,改进除法运算,见课本王老师的附录讲解
一开始我也是看别人文章,跟别人学习怎么让程序处理数据,怎么定义数据段,然后才有了这个程序
整个程序由以下几个函数段(代码段)实现
aver:计算每一年的平均收入
show:显示整个表,其又调用了以下代码段
shinit:对屏幕进行初始化,就是清空屏幕,先显示一遍整屏幕的黑底空字符
shyear:显示年份,因为存储的直接就是年份的ascii码值
shlarg:显示每年总收入,因是双字,数据较大,二进制转十进制时除法运算会溢出,采用改进的除法运算,10进制各位字符入栈,再弹出至显存
shsmal:显示每年人均收入和每年的员工数。属于小型整数,采用了正常标准的除法运算,进行进制转换
assume cs:code,ds:data
data segment
db '1975','1976','1977','1978','1979';偏移量bx
db '1980','1981','1982','1983','1984','1985','1986','1987','1988','1989'
db '1990','1991','1992','1993','1994','1995'
dd 16,22,382,1356,2390
dd 8000,16000,24486,50065,97479,140417,197514,345980,590827,803530
dd 1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28;偏移量si
dw 38,130,220,476,778,1001,1442,2258,2793,4037
dw 5635,8226,11542,14430,15257,17800
dw 21 dup (0)
dw 30 dup (0);栈段,可以容纳30个字,总共84+84+84+60=252+60=312字节
data ends
code segment
main:
mov ax,data
mov ds,ax
mov ss,ax
mov sp,312
mov bx,84
mov si,168;设置数据段偏移量
mov cx,21
call aver
mov bx,0
call show
mov ax,4c00h
int 21h
aver:
push ax
push bx
push cx
push dx
push ds
push si
avloop:
mov ax,ds:[bx]
mov dx,ds:[bx+2]
div word ptr ds:[si]
mov ds:[si+42],ax
add bx,4
add si,2
loop avloop
pop si
pop ds
pop dx
pop cx
pop bx
pop ax
ret
show: call shinit
push ax
push cx
push es
push bp
push di
mov ax,0b800h;设置显存段
mov es,ax
mov bp,4;行首偏移量,俩字符
mov di,0
shlp:
push cx
mov di,0
call shyear
mov di,20
add bx,84
call shlarg
sub bx,84
mov di,60
call shsmal
mov di,90
add si,42
call shsmal
sub si,42
pop cx
add bx,4
add si,2
add bp,160
loop shlp
pop di
pop bp
pop es
pop cx
pop ax
ret
shinit:
push ax
push bx
push cx
push dx
push di
push es
mov ax,0b800h
mov es,ax
mov bx,0;设置显存段
mov di,0
mov cx,25
mov dx,0
iniout:
push cx
mov cx,80
iniin:
mov es:[bx+di],dx
add di,2
loop iniin
add bx,160
sub di,di
pop cx
loop iniout
pop es
pop di
pop dx
pop cx
pop bx
pop ax
ret
shyear:
push ax
push bx
push cx
push es
push bp
mov cx,4
yeargo:
mov al,ds:[bx]
mov ah,0dh
mov es:[bp],ax
add bp,2
inc bx
loop yeargo
pop bp
pop es
pop cx
pop bx
pop ax
ret
shlarg:
push ax
push bx
push cx
push dx
push ds
push si
push es
push di
push bp;寄存器不够用,si指向bp,si bp另作它用
mov si,sp
mov ax,ds:[bx]
mov dx,ds:[bx+2]
mov bx,10;bx保存除数
larggo:
mov bp,ax;bp为低16位
mov ax,dx
mov dx,0
div bx
push ax;保存高位除法的商部分
mov ax,bp
div bx;至此dx得到了第一个余数,应保存在cx里
mov cx,dx
add cx,48
mov ch,0dh;形成ascii码,还有显示属性
pop dx
push cx;字符入栈,商也由dx ax保存,用cx依次检验ax和dx是否为0
mov cx,ax
jcxz latehi;large test high
jmp larggo
latehi:
mov cx,dx
jcxz largok;商为0,则表示转换完成
jmp larggo
largok:
mov ax,si
sub ax,sp
mov bl,2
div bl
mov cl,al
mov ch,0
mov bp,ss:[si]
largwr:
pop es:[bp+di]
add di,2
loop largwr
pop bp
pop di
pop es
pop si
pop ds
pop dx
pop cx
pop bx
pop ax
ret
shsmal:
push ax
push bx
push cx
push dx
push ds
push si
push es
push bp
push di
mov ax,ds:[si]
mov si,sp
mov bx,10
smallp:
mov dx,0
div bx
add dx,48
add dh,0dh
push dx
mov cx,ax
jcxz smalok
jmp smallp
smalok:
mov ax,si
sub ax,sp
mov bl,2
div bl
mov cl,al
mov ch,0
smalwr:
pop es:[bp+di]
add di,2
loop smalwr
pop di
pop bp
pop es
pop si
pop ds
pop dx
pop cx
pop bx
pop ax
ret
code ends
end main
插入汇编代码我不知道用什么类型规范代码。
编辑器用的是Win-Masm,前辈高人开发的,比记事本强多了。显示行数,高亮关键字很有用
代码里有注释,复制到编辑器里看一遍就会了,谢谢阅读