王爽汇编语言课程设计1

来源:互联网 发布:人工智能 图书馆 编辑:程序博客网 时间:2024/05/19 18:48
assume cs:code,ds:data,es:powerIdeapowerIdea 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,17800powerIdea endsdata segment        db 11 dup ('0') ;用来存放10进制格式字符串,以‘0’结尾,由于double word型                        ;数据转化成10进制字符串不会超过十位,再加上末尾的'0',共                        ;11位,所以这里用11个字节存放data endscode 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,程序执行后由于按下了回车,将出现在第0sub 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存放高16pop 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                      retcode endsend start
0 0