您的位置:首页 > 其它

王爽汇编语言课程设计1

2017-01-02 20:09 721 查看
assume cs:code,ds:data,es:powerIdea

powerIdea segment
db '1975',
4000
'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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  汇编语言