;文件名:pdesign1
;任务:将data中数据,按“年份、年收入、雇员人数”及“人均收入”在屏幕上逐行显示
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,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,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
code segment
start: mov ax,data ;设置数据段地址
mov ds,ax
mov si,0
mov bp,0b800h ;设置写入字符显示缓冲区段地址
mov es,bp
mov di,0
mov bh,2 ;设置接口参数——显示屏起始行
call Primary_pro ;转到Primary_pro
mov ax,4c00h
int 21h
Primary_pro:
sub bp,bp ;清0
mov cx,21 ;设置21个循环
s: push cx ;入栈保护(cx)
mov cx,4 ;(一)读写入年份
sub ax,ax ;置0
push ax ;先压入结束标识0
mov si,3
ye: mov al,ds:[bp][si] ;逆读各年份
push ax ;入栈
dec si ;寻址自减
loop ye
mov bl,3 ;设置接口参数
call show_str ;转到子程序,处理“年份”字符着色及显示
mov ax,ds:84[bp] ;(二)读写入年收入;年收入的低16位
mov dx,ds:84[bp].2 ;年改入的高16位
call dtoc
mov bl,12 ;显示屏起始列
call show_str ;处理“年收入”字符着色及显示
mov ax,168[di] ;(三)读写入年雇员;雇员人数作为被除数
mov dx,0 ;设置接口参数,高16位添加0,成为32位
call dtoc ;
mov bl,22 ;显示屏起始列
call show_str ;处理“雇员人数”
mov ax,ds:84[bp] ;(四)计算年人均收入;年收入的低16位
mov dx,ds:84[bp].2 ;设置接口参数,年改入的高16位
mov cx,168[di] ;读取雇员人数作为除数
call divdw ;获得dw型人均收入数据
mov dx,0 ;高16位置0,合成32位
call dtoc
mov bl,30 ;显示屏起始列
call show_str ;处理“人均收入”
pop cx ;出栈恢复数据
inc bh ;行自增1,
add di,2 ;读取下一个数据
mov bp,di ;处理bp与di的关系。引用ruder帖,bp=2di
add bp,bp
loop s ;循环
ret ;出栈
;1.dtoc子程序描述
;任务:将dword型数据处理为10进制数“0~9”的ASCⅡ码
;参数:(dx)=(dword型数据的高16位)
; (ax)=(dword型数据的低16位)
;返回:无
dtoc:
pop si ;将ip出栈暂存
mov cx,0
push cx ;压入结束标识0
dr: mov cx,10 ;除数
call divdw ;转到除法溢出子程序处理
add cx,30h ;制作10进制数“0~9”的ASCⅡ码
push cx ;压栈
mov cx,ax ;将商送入cx
jcxz d_ovr ;判断商为0否,为0跳到d_ovr,否则继续
jmp dr ;转到标号 dr 处执行
d_ovr:
push si ;入栈栈恢复ip
ret ;转到ip所指处,继续执行
;2.divdw子程序描述
;任务:使可能产生的除法溢出得到处理,避免溢出。
;参数:(dx)=(dword型数据的高16位)
; (ax)=(dword型数据的低16位)
; (cx)=(除数)
;返回:(dx)=(商的高16位)
; (ax)=(商的低16位)
; (cx)=(余数)
divdw:
push bx ;入栈保护
push ax ;......
mov ax,dx ;高16位H除法
mov dx,0 ;高位加0化为32位
div cx
mov bx,ax
pop ax ;这一步精彩,引自viking的帖。
div cx ;它充分运用了现dx中的高16位余数,
;作为这次低16位除法的高16位数。
mov cx,dx ;传递余数
mov dx,bx ;将bx中商的高16位传递到dx
pop bx ;(ax)在之前已出栈,在此只有(bx)需出栈
ret ;转到ip所指处,继续执行
;3.show_str子程序描述
;任务:将10进制数“0~9”的ASCⅡ码显示在参数指定的显示屏幕上
;参数:
; (bh)=(传入第1个字符写入屏幕的行数)
; (bl)=(传入第1个字符写入屏幕的列数)
;
;返回:无
show_str:
;计算在(bh)行(bl)列写入第1个字符的位置
mov al,160 ;1行的字节数
mul bh ;8位乘法,al*bh
mov si,ax ;从ax取出乘积
mov al,2 ;1列每个字符占2个字节
mul bl ;al*bl
add si,ax ;加入相乘结果,得第1个字符位置
pop dx ;将ip出栈暂存
sss: pop cx ;数据出栈
jcxz s_ovr ;读到结束标识0,则转到s_ovr准备结束
mov ch,00000010b ;传入颜色,制作彩色字符
mov es:[si],cx ;在指定位置写入彩色字符
add si,2 ;写入数据地址增2字节
jmp short sss ;转到sss处,继续处理下一个
s_ovr: push dx ;入栈栈恢复ip
ret ;转到ip所指处,继续执行
code ends
end start
- [游客] 为啥简版的int 13h之后不用 jmp 也行。 08/31 00:14
- [hky987654321] 是的,按压F1的次数 >=15 ,有“按下“→”键会出现光斑落在年份的百位数上”的现象。 这与缓冲 08/09 11:12
- [游客] 为什么多次按F1后,按下“→”键会出现光斑落在年份的百位数上? 08/02 21:42
- [游客] 懂了。 07/30 10:54
- [hky987654321] -1就是FFh。用-1兼济了ffff:0和简洁的数据分隔这二者的需要。 [bp-2],是因为刚进入 07/29 11:43
- [游客] 也看不懂[bp-2] 07/12 10:49
- [游客] 不懂-1 07/09 17:55
- [游客] 16位现在只有教学意义,看一眼就好。 04/13 00:46
- [游客] 没搞错吧,课程2才351b 03/09 18:01
- [游客] 没想到实验14只用13条代码! 03/02 15:46