assume cs:code,ds:data,es:powerIdea
powerIdea 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
powerIdea ends
data segment
db 11 dup ('0') ;用来存放10进制格式字符串,以‘0’结尾,由于double word型
;数据转化成10进制字符串不会超过十位,再加上末尾的'0',共
;11位,所以这里用11个字节存放
data ends
code segment
start:call clear_screen ;先清屏
mov ax,data ;将ds:si指向data段第一个元素
mov ds,ax
sub si,si
mov ax,powerIdea ;将es:di指向powerIdea段第一个元素
mov es,ax
sub di,di
sub bx,bx ;将bx清零,用来定位雇员数
mov dh,1 ;dh为行号,将dh置1,程序执行后由于按下了回车,将出现在第0行
sub cx,cx ;将cx清零
mov cl,02h ;将02h赋给cl,show_str中cl用来决定字符串的颜色
;此处为绿色
;如果dh为22,则说明已经进行了21此循环,应结束程序
l:push cx ;保存cx
sub ch,ch ;将行号dh的值赋给cx,再用jcxz指令判别cx是否为22
mov cl,dh ;若是则说明程序应当结束
sub cx,22
jcxz done
pop cx ;恢复cx
mov ax,es:0[di] ;将年份的头两个字节移动到ds:si处
mov [si],ax
mov ax,es:0[di+2] ;将年份的后两个字节移动到ds:si+2处
mov [si+2],ax
mov byte ptr [si+4],0 ;末尾补0作为结束符,此时ds:si即有一个以零结尾的10进制形式字符串
mov dl,2 ;dl决定ds:si处的字符串的列号
call show_str ;行号(dh)、列号(dl)、颜色(cl)和字符串首地址都已确定
;调用show_str即可在相应位置显示
call clear ;将ds:si处往后的11个字节清零,也可不进行此操作
push dx ;将dx压栈,因为后面需用到dx
mov ax,es:84[di] ;将收入的前两个字节送入ax作为要转化数据的低16位
mov dx,es:84[di+2] ;将收入的后两个字节送入dx作为要转化数据的高16位
call dtoc ;要转化的double word型数据以确定,目的地址ds:si也已确定,调用dtoc开始转化
pop dx ;恢复dx
mov dl,12 ;设置字符串将在第12列显示
call show_str ;显示字符串
call clear
push dx ;将dx压栈,因为后面需用到dx
mov dx,es:84[di+2] ;由于前面只改变了dx而没有改变ax
;所以此处重新将收入的后两个字节送入dx,使dx,ax表示收入
push cx ;将cx压栈,因为后面需用到cx
mov cx,es:168[bx] ;将雇员人数送入cx设置除数,divdw的参数中cx表示除数,ax表示被除数低16位
;dx表示被除数高16位
call divdw ;进行无溢出除法,结果为32位,ax存放低16位,dx存放高16位
pop cx ;恢复cx
call dtoc ;开始将(收入/雇员人数)的结果进行转化
pop dx ;恢复dx
mov dl,32 ;设置字符串将显示在第32列
call show_str;显示字符串
call clear
push dx ;将dx压栈,因为后面需用到dx
mov ax,es:168[bx] ;准备转化雇员人数,用雇员人数设置ax,dx清零,
sub dx,dx
call dtoc ;开始转化
pop dx ;恢复dx
mov dl,22 ;设置雇员人数将显示在第22列
call show_str ;显示字符串
call clear
add dh,1 ;行数递增
add di,4 ;用于定位double word型数据的di加4
add bx,2 ;用于定位word型数据的bx加2
jmp short l
done:pop cx ;弹出执行jcxz done指令前压入的cx
mov ax,4c00h
int 21h
;名称:dtoc,需用到无溢出除法divdw
;功能:将double word型数据转化为表示一个十进制数的字符串,以0结尾
;参数:(ax)=dw型数据低16位,(dx)=dw型数据高16位,ds:si指向字符串首地址
;返回:无
dtoc:push ax ;将需要用到的寄存器压栈
push cx
push dx
push si
sub cx,cx ;将0入栈,作为结尾字符0
push cx
mov cx,0ah ;设置除数
dtoc_l0:call divdw ;调用无溢出除法
add cx,30h ;将余数加30h得到十进制各位数值的ASCII码
push cx ;将得到的结果压栈
push dx ;将dx,ax压栈,保存商
push ax
or dx,ax ;判断商是否为0,若是则转到dtoc_p处执行
mov cx,dx
jcxz dtoc_p
pop ax ;将商还原到ax,dx,
pop dx
mov cx,0ah ;重新设置除数
jmp short dtoc_l0 ;循环执行
dtoc_p:pop ax ;将最后保存的商(ax=0000,dx=0000)出栈
pop dx
dtoc_l1:pop ax ;将栈中数据弹出到ax中
mov [si],al ;将数据低8位(十进制数各位数值+30H)送入目的地址
mov cx,ax ;判断是否读到了0,若是则跳转到done0处执行
jcxz dtoc_done
inc si ;si=si+1,循环执行
jmp short dtoc_l1
dtoc_done:pop si
pop dx
pop cx
pop ax
ret
;无溢出除法
;输入:ax:被除数低16位,dx:被除数高16位,cx:除数
;输出:ax:结果低16位,dx:结果高16位,cx:余数
;X:被除数,[0,ffffffff]
;N:除数,[0,ffff]
;H:X高16位,[0,ffff]
;L:X低16位,[0,ffff]
;int():取商
;rem():取余数
;公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
divdw: push bx ;用到的寄存器入栈
divdw_p:mov bx,ax ;用bx保存被除数低16位(L)
mov ax,dx ;将被除数高16位(H)送入ax,准备进行除法运算(H/N)
sub dx,dx ;将dx清零
div cx ;高16位(H)除以除数
push ax ;将(H/N)的商压栈保存,作为最终结果的高16位
mov ax,bx ;将低16位(L)送入ax,连同(H/N)的余数(此时在dx中)一起除cx
div cx
mov cx,dx ;最终商放在ax中,余数送入cx
pop dx ;将(H/N)的商送入dx作为结果的高16位
divdw_done: pop bx ;用到的寄存器出栈
ret
;名称:clear
;功能:将ds:si开始的11个字节的数据置零
;参数:ds:要归零数据的段地址;si:要归零数据的偏移地址
;返回:无
clear:push cx ;将要用到的寄存器入栈
push si
mov cx,11 ;设置循环次数等于11
clear_l:mov byte ptr [si],0 ;将ds:si置零
inc si ;递增si
loop clear_l
done:pop si ;恢复用到的寄存器值
pop cx
ret
;在指定位置,用指定颜色,显示一个用0作为结束符的字符串
;参数:dh:行号;dl:列号;cl:颜色;ds:si指向字符串首地址
;返回:无
show_str:push di ;保存需用到的寄存器
push dx
push es
push bx
push cx
push si
push ax
show_str_p:mov al,0a0h ;dh*a0h+dl*02h即为相对于b8000的偏移
mul dh
mov bx,ax ;用bx保存dh*a0h的结果
mov al,02h
mul dl ;计算dl*02h
add ax,bx ;计算dh*a0h+dl*02h
mov di,ax ;将偏移地址送入di
mov ax,0b800h ;设置段地址,用es保存
mov es,ax
mov bl,cl ;由于jcxz指令要用到cl,所以用bl来保存cl的值
show_str_l:mov cl,[si] ;用jcxz指令判断是否遇到0,如果是者跳转到done,结束程序
mov ch,0
jcxz show_str_done
mov es:[di],cl ;开始往目的地址处转移数据
mov es:[di+1],bl ;转移颜色数据
inc si ;源地址+1
add di,2 ;目的地址+2
jmp short show_str_l ;跳转到l
show_str_done:pop ax ;恢复寄存器值
pop si
pop cx
pop bx
pop es
pop dx
pop di
ret
;名称:clear_screen
;功能:清屏(80*25)
;参数:无
;返回:无
clear_screen:push ax ;保存用到的寄存器
push cx
push ds
push bx
mov cx,07d0h ;设置循环次数为2000
mov ax,0b800h ;设置显存段地址
mov ds,ax
mov bx,0 ;偏移地址置为0
clear_screen_l:mov word ptr [bx],0 ;设置要显示的内容为0000(黑色)
add bx,2 ;偏移地址加2
loop clear_screen_l
clear_screen_done:pop bx ;恢复用到的寄存器值
pop ds
pop cx
pop ax
ret
code ends
end start
王爽汇编语言课程设计1
最新推荐文章于 2024-08-10 15:27:23 发布