荣誉值:0
信誉值:0
注册日期:2010-08-20 21:47 |
assume cs:code
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983' 年份
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2396,8000,16000,24486,50065,97479,140417,197514 收入
dd 345980,590872,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226 雇员数
dw 11542,14430,15257,17800
data ends
table segment 也是论坛找到的思路,上面的数据全部写进这里,并转换成ASCII码,
db 972 dup (0) 年份0-4(5字节),收入5-15(11字节),人数16-21(6字节),
table ends 平均数22-31(10字节)
stack segment
dw 32 dup (0) 这是要用到的栈
stack ends
code segment
start:mov ax,0600h 这是论坛上找的清屏,因为是新手,前面书上没学过,所以不知道什么意思,注释
mov bh,3ah 不了。。。。,所以想请高手们详细注释一下
mov cx,0000h
mov dx,184fh
int 10h
mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov ax,stack
mov ss,ax
mov sp,64 以上是设置寄存器
mov cx,21 循环21次
mov bx,0 data数据使用,并且是双字(四字节)
mov si,0 data数据使用,是单字(双字节)
mov di,0 table数据使用,以20H字节为单位
s:push [bx]
push 2[bx]
pop es:2[di]
pop es:[di] 以上是年份入栈,出栈写入table中,4字节
mov byte ptr es:4[di],0h 年份后面加0结尾识别值.
push 054h[bx]
push 056h[bx]
pop es:7[di]
pop es:5[di] 以上总额收入栈,出栈写入 4字节
push 0a8h[si]
pop es:16[di] 是人数入栈,出栈写入 2字节
mov ax,es:5[di]
mov dx,es:7[di]
push cx
mov cx,es:16[di]
call divdw 子程序计算平均数,是为防溢出,虽然在第七实验中不会溢出,可是这个也是为后
pop cx 面程序计算,转换ASCII码也要用到
mov es:22[di],ax
mov es:24[di],dx 平均数写入table中
add bx,4 读年数字符与总额时增量为4字节
add si,2 读人数时增量为2字节
add di,32 写数据时每行数据间为32字节增量
loop s
mov ax,table 把data数据写入table中,data就用不到了
mov ds,ax 设置table寄存器
mov bx,0
mov di,0
mov cx,21 循环21次
s1:mov ax,5[bx]
mov dx,7[bx] 平均数转换ASCII码
mov si,bx
add si,5
call dtoc 子程序使用转换ASCII码
mov ax,16[bx] 人数换ASCII码
mov dx,0
mov si,bx
add si,16
call dtoc
mov ax,22[bx] 平均数换ASCII码
mov dx,24[bx]
mov si,bx
add si,22
call dtoc
add bx,32
loop s1 年份已经是ASCII码了,所以不用转换
mov ax,table 转换完ASCII码后,设置显屏
mov ds,ax
mov bx,0
mov cx,21 重复循环21次
mov dh,4 显屏行数
s2:push cx
mov cx,2 设置颜色是绿色,也可以根据实验8的资料转换颜色。
mov dl,6 年份显屏的列数
mov si,0 年份ASCII码的偏移地址
call show 显屏的子程序
mov dl,16 总额收入显屏的列数
add si,5 总额收入ASCII码的偏移地址增量
call show
mov dl,30 人数显屏的列数
add si,11 人数ASCII码的偏移地址增量
call show
mov dl,40 平均数显屏列数
add si,6 平均数ASCII码的偏移地址增量
call show
inc dh 显屏行数增量
add bx,32 table数据每行数据间32字节增量
pop cx
loop s2
mov ax,4c00h
int 21
divdw:push bx 子程序:解决除数溢出问题 参考实验10的第二小题
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax
pop ax
div cx
mov cx,dx
mov dx,bx
pop bx
ret
dtoc:push ax 子程序:转换ASCII码
push bx
push cx
push dx
push si
push di 保存数据入栈
mov bx,0
mov di,si
dtoc_1:mov cx,10 被除数
call divdw
add cx,30h ASCII码
mov [si],cl
inc si
inc bx
mov cx,ax
jcxz dtoc_2
jmp dtoc_1
dtoc_2:mov cx,bx 把ASCII码设置转换成从左到右的正常顺序
mov si,di
dtoc_3:mov al,[si]
push ax
inc si
loop dtoc_3
mov cx,bx
mov si,di
dtoc_4:pop ax
mov [si],al
inc si
loop dtoc_4
mov byte ptr [si],0 加0结尾识别值.
pop di
pop si
pop dx
pop cx
pop bx
pop ax 把保存数据出栈
ret
show:push ax 子程序:把数据颜色显屏
push bx
push cx
push dx
push es
push si
push di
mov ax,0b800h
mov es,ax
mov di,0a0h 显屏区地址
mov ax,di
mul dh 乘行数得出地址
mov di,ax
mov ax,2
mul dl 乘列数得出地址
sub ax,2
add di,ax 行加列,正式得出显屏地址
mov ah,cl 颜色入寄存器
show_1:mov cl,[si+bx] ASCII码入寄存器
mov ch,0
jcxz show_2
mov al,cl
mov es:[di],ax 数据与颜色写入显屏区
inc si
add di,2
jmp short show_1
show_2:pop di
pop si
pop es
pop dx
pop cx
pop bx
pop ax
ret
完成子程序
code ends
end start
因为之前没啥基础,是个完全的新人,所以感觉就算有了参考,可是加以理解并写出自己的程序还是进度很慢,第一段程序转为简单,第二段子程序最后部分纠结几天,还是因为之前没有融会贯通,第三段程序还好,有了前两个的基础,可以很快的写出来,前前后后,可以说将近花了快一个月,不是每天都有空来思考各写程序的,因为工作的原因有时两天没碰,有时更有三天没碰过了。 | | |