汇编语言-课程设计一

;程序目标为在屏幕指定位置显示数据
;数据分为四项:年份、收入、员工数、人均收入;其中人均收入要通过计算得出
;上述数据又分为两大类:字符类:如年份;数字类:(收入、员工数、人均收入)
;字符类不需要转换可直接存入显示缓冲区
;数字类需要先转换为对应字符,再存入显示缓冲区
;程序设计思路如下:
;第一步:求出人均收入存入data指定区域(设计子函数1:避免溢出的dword/word型运算)
;第二步:在指定区域显示年份数据(设计子函数2:显示指定内存区的数据到屏幕指定位置)
;第三步:将指定区域dword型数字数据转换成字符串并显示(设计子函数3:转换dword型数据为字符串,存入指定显示缓冲区)
;第四步:将指定区域word型数字数据转换成字符串并显示(设计子函数4:转换word型数据为字符串,存入指定显示缓冲区)
;在第二步显示数据之前,先进行清屏,因此设计子函数5进性清屏


assume cs:code
stack segment
    dw 0,0,0,0,0,0,0,0
stack ends
;******************************数据段******************************
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'
    ; 以上为21个年份的字符串,地址空间为data:0~53H
  dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ;以上为21年公司收入数据,地址空间为data:54H~0a7H
  dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635
  dw 8226,11542,14430,15257,17800
    ;以上为21年公司员工人数,地址空间为data:0a8H~0d1H
  dd 21 dup (0)     ;预设21个人均年创收数存储区,地址空间为data:0d2H~0fcH
  dw 10            ;寄存器不够用=。=存储临时除数
data ends
;**************************数据段设置结束**************************
code segment
start:
    mov ax,stack
    mov ss,ax
    mov sp,16

    mov ax,data
    mov ds,ax

    mov ax,0b800h
    mov es,ax
;**************************计算人均收入**************************
    mov si,84    ;调用子函数1之前参数设置
    mov di,168
    mov bx,210
    mov cx,21
mains1:
    call div_dd
    add si,4
    add di,2
    add bx,4
    loop mains1
;******************************清屏******************************
    call clear_scr

;**************************显示年份数据**************************
    mov bx,0    ;调用子函数2之前参数设置
    mov bp,160
    mov cx,21
mains2:
    mov si,0
    push cx
    mov cx,4
mains3:
    call show_year
    add si,2
    inc bx
    loop mains3
    add bp,160
    pop cx
    loop mains2

;**************************显示收入数据**************************
    mov bx,84    ;调用子函数3之前参数设置
    mov bp,180
    mov cx,21
mains4:
    mov di,0
    call ddshow
    add bx,4
    add bp,160
    loop mains4

;**************************显示员工数据**************************
    mov bx,168    ;调用子函数4之前参数设置
    mov bp,200
    mov cx,21
mains5:
    mov di,0
    call word_show
    add bx,2
    add bp,160
    loop mains5

;**************************显示人均收入数据**************************
    mov bx,210    ;调用子函数3之前参数设置
    mov bp,220
    mov cx,21
mains6:
    mov di,0
    call ddshow
    add bx,4
    add bp,160
    loop mains6

    mov ax,4c00h
    int 21h


;******************************子函数1*******************************
;功能:将dword型数据除以word型数据的商,商为dword型
;入口参数:ds:si指向dd型被除数,ds:di指向dw型除数,
;       结果dd型商存放在ds:bx处
;返回:无
div_dd:
    push ax
    push dx
    mov dx,0
    mov ax,[si+2]
    div word ptr [di]
    mov [bx+2],ax
    mov ax,[si]
    div word ptr [di]
    mov [bx],ax
    pop dx
    pop ax
    ret


;******************************子函数2*******************************
;功能:将指定区域的数据显示到屏幕指定位置
;入口参数:ds:bx指向要写入的数据区域;es:[bp+si]指向屏幕指定位置的显示缓冲区
;返回:无
show_year:
    push ax
    mov al,[bx]
    mov es:[bp+si],al
    mov byte ptr es:[bp+si+1],02h
    pop ax
    ret

;******************************子函数3*******************************
;功能:转换dword型数据为字符串,存入指定显示缓冲区
;入口参数:ds:bx指向被转换的dword型数据,es:[bp+di]指向显示缓冲区存放位置
;返回:无
ddshow:
    push ax
    push bx
    push cx
    push dx
    push si            ;入栈保护子函数用到的寄存器

    mov dx,ds:[bx+2]
    mov ax,ds:[bx]        ;设置被转换数
    mov si,0        ;设置位数计数器

s1:    push ax            ;暂存被除数低16位
    mov ax,dx
    mov dx,0
    div word ptr ds:[294]    ;结果商为最终商的高16位
    mov bx,ax        ;暂存最终商的高16位
    pop ax            ;取出被除数低16位
    div word ptr ds:[294]    ;结果商为最终商的低16位,在ax中;余数为最终余数在dx中
    push dx            ;入栈存储余数
    inc si            ;位数增1
    mov dx,bx        ;取出最终商的高16位;最终商的低16位在ax中,最终商作为新的被除数进入下一循环
    mov cx,ax
    jcxz ok1
    jmp short s1

ok1:
    mov cx,dx
    jcxz ok2
    jmp short s1

ok2:
    mov cx,si               ;设置循环次数
s2:
    pop ax
    add al,30h        ;转换为字符
    mov es:[bp+di],al        ;写入显示缓冲区
    mov byte ptr es:[bp+di+1],02h    ;设置字符属性
    add di,2
    loop s2
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    ret

;******************************子函数4*******************************
;功能:转换word型数据为字符串,存入指定显示缓冲区
;入口参数:ds:bx指向被转换的word型数据,es:[bp+di]指向显示缓冲区存放位置
;返回:无
word_show:
    push ax
    push bx
    push cx
    push dx
    push si
    mov ax,ds:[bx]        ;设置被转换数
    mov si,0        ;设置位数计数器
s3:
    mov bl,al        ;暂存被除数低8位
    mov al,ah
    mov ah,0
    div byte ptr ds:[294]
    mov bh,al        ;暂存最终商高8位
    mov al,bl        ;取出暂存的被除数低8位
    div byte ptr ds:[294]    ;此时商为最终商低8位,在al中,余数在ah中
    mov bl,ah        ;暂存最终余数
    mov ah,bh        ;取出最终商高8位,ax作为新的被除数
    push bx            ;余数(bl)入栈存储
    mov cx,ax
    inc si        
    jcxz ok3
    jmp short s3
ok3:
    mov cx,si    ;位数作为循环次数
s4:    
    pop ax    
    add al,30H
    mov es:[bp+di],al
    mov byte ptr es:[bp+di+1],02h
    add di,2
    loop s4
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    ret
;******************************子函数5*******************************
;功能:清屏指定区域
;入口参数:子函数内置设置
;返回:无
clear_scr:
    push bp
    push cx
    mov bp,0
    mov cx,22
s5:
    mov si,0
    push cx
    mov cx,80
s6:
    mov byte ptr es:[bp+si],0
    mov byte ptr es:[bp+si+1],0
    add si,2
    loop s6
    add bp,160
    pop cx
    loop s5
    pop cx
    pop bp
    ret

code ends
end start

 

posted @ 2013-08-28 16:34  tsembrace  阅读(2194)  评论(1编辑  收藏  举报