讲道理关于这道题,真的哎呀痛苦是一方面,其实真的不怎么想写,不过最后还是去把这个程序自己给调试了一下
题目如下所示
这里其实就是需要注意的就是寄存器的保护,以及之前几篇文章中讲的函数的调用
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
temp segment
db 10 dup(0)
temp ends
stack segment
db 64 dup(0)
stack ends
code segment
start:
mov ax,stack ;设置栈段
mov ss,ax
mov sp,64 ;设置sp
mov ax,data
mov es,ax ;设置es数据段
mov ax,temp ;设置data数据段
mov ds,ax ;设置数据段
mov si,0 ;设置寄存器的初始值
mov bp,0
mov bx,0
mov di,0
mov cx,21
s: push cx ;压入cx
mov ax,es:[bx] ;给数据的1975,以0结束在write_str
mov ds:[si],ax ;ds是ax
mov ax,es:[bx+2] ;es为data段当中的
mov ds:[si+2],ax ;比如说第二个数据1976,39给的是ah,al给的是31
mov byte ptr ds:[si+4],0 ;第5个数据给0在write_str里面使用
mov dh,24 ;
sub dh,cl ;24-21从第三行开始
mov dl,3 ;从第三列开始
mov cl,2 ;给cl为2为绿色
call show_str ;调用show_str函数
push dx ;保存每行每列
mov ax,es:[84+bp]
mov dx,es:[84+bp+2]
call dtoc
pop dx
add dl,10 ;从第三列开始往后加的列数,比如说1975如果这里为4那么下一个数据会紧跟其后
call show_str
push dx ;保存dx,因为dtoc子程序会用到dx
mov ax,es:[168+di] ;展示雇员数量
mov dx,0
call dtoc ;调用转换的方法
pop dx ;
add dl,10
call show_str
push dx
push cx
mov ax,es:[84+bp]
mov dx,es:[84+bp+2]
mov cx,es:[168+di]
call divdw ;调用防止移除除法程序
call dtoc
pop cx
pop dx
add dl,10
call show_str
add bx,4 ;bx跨四个字节的数据因为比如说1975就是四个字节
add bp,4 ;收入就是四个字节数据,所以加4
add di,2 ;雇员数
pop cx
loop s
mov ax,4c00h
int 21h
show_str:
push ax ;压入ax
push bx ;压入bx
push cx ;压入cx
push si ;压入si
push di ;因为之后都还要使用
push es
mov bl,cl ;给bl位2,也就是绿色
mov bh,0
mov ax,0b800h
mov es,ax
mov al,0a0h
mov ah,0
mul dh ;哪一行
mov di,ax
mov al,2h
mov ah,0
mul dl ;哪一列
add di,ax
write_str: ;写入字符的函数
mov ch,0
mov cl,[si]
jcxz ok
mov es:[di],cl ;属于哪个字符
mov es:[di+1],bl;绿色写入进去
inc si
add di,2
jmp short write_str
ok:
pop es ;出栈操作
pop di
pop si
pop cx
pop bx
pop ax
ret
divdw:
push bx ;都要保存这个bx,因为前面取1975那些数据的时候会用到
push ax ;ax先入栈,因为之后的结果会影响ax
mov ax,dx ;将dx先给cx,要先把高16位先做除法
mov dx,0 ;把dx置为0
div cx ;如果除数为16位,则被除数为32位,ax为商,dx为余数
mov bx,ax ;将ax的值给bx
pop ax ;找回ax原先的值
div cx ;注意此时dx为余数的值还没变,这里dx为5,所以就是0x54240/0x0A = 0x86A0
mov cx,dx ;保存余数到cx
mov dx,bx ;设置最高位为dx也就是第一次除法运算得到的ax
pop bx
ret
dtoc:
push bx
push cx
push si
mov cx,0
push cx
mov bx,1
div_continue: ;除法运算
mov cx,10 ;设置cx,作为除数
call divdw ;调用除法函数
add cx,30H ;加30
push cx ;将cx压栈
inc bx ;算除法了几次
mov cx,ax ;
jcxz jumpZero ;如果cx为0,就跳到jumpZero
jmp div_continue ;跳到div_continue
jumpZero:
mov cx,bx ;余数个数
remainder_move:
pop bx ;保存的算的余数的值
mov ds:[si],bx ;赋值给ds:[si]
inc si
loop remainder_move
pop si
pop cx
pop bx
ret
code ends
end start
程序运行结果