荣誉值:0
信誉值:2
注册日期:2011-02-09 21:07 |
;Title: Curriculum Design One
;File: cd1.asm
;Function: Display the data of Power Idea in the form of Table Under DOS
;Note: A Looking Concise Solution, Solve this Question in One Layer of Loop, but have to be Careful When Dealing with Registers.
;Author: Chao Zhou
;Date: 02-21-2011
;标题: 课程设计一
;文件: cd1.asm
;功能: 在DOS下以表格的形式显示Power Idea公司的数据
;注意: 一个看起来比较简洁的方案,使用一层循环解决这个问题,但是在处理寄存器的时候必须小心。
;作者: 周超
;日期: 02-21-2011
assume cs:codesg
;各组数据在data区的起始地址
YEAR_ARRRY EQU 0H
SUMM_ARRAY EQU 84
COUNT_ARRAY EQU 168
;各列数据起始列
YEAR_LINE EQU 6
SUMM_LINE EQU 18
COUNT_LINE EQU 30
AVER_LINE EQU 42
data segment
;表示21年年份,字符串
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年总收入,dword
dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514
dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000
;雇员人数 dword
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
table segment
;第一行显示内容
LINE1 db ' Basic Situation Of The Power Idea Company ',0
;第二行显示内容
LINE2 db '---------------------------------------------------------',0
;第三行显示内容
LINE3 db ' Year Income Number Average',0
table ends
;缓冲区,用于缓冲用作显示的字符串
buff segment
db 100h dup(0)
buff ends
stack segment
db 100h dup(0)
stack ends
codesg segment
;********************************************************************
;名称: main
;说明: 程序入口
;参数: 无
;返回: 无
;********************************************************************
main:
mov ax, stack
mov ss, ax
mov sp, 20h
;------------表头------------
mov ax, table
mov ds, ax
mov dl, 0
mov si, offset LINE1
mov dh, 0
mov cl, 0CH
call show_str ;显示表头第一行
mov si, offset LINE2
mov dh, 1
mov cl, 0FH
call show_str ;显示表头第二行
mov si, offset LINE3
mov dh, 2
mov cl, 0FH
call show_str ;显示表头第三行
;------------表内容------------
mov ax, data
mov es, ax
;ds指向缓冲区,后续用于缓冲用作显示的字符串
mov ax, buff
mov ds, ax
;------------按行显示表内容------------
mov di, 0
mov bp, 0
mov bl, 3 ;从第三行开始显示表内容
mov si, 0
mov cx, 21
output_oneline:
;------------每次循环显示一行中的各列内容------------
push cx
mov cl, 2 ;颜色
;------------年份------------
mov ax, es:YEAR_ARRRY[bp]
mov dx, es:YEAR_ARRRY[bp + 2]
mov ds:[0], ax
mov ds:[2], dx
mov ax, 0
mov ds:[4], ax
;在屏幕上打印
mov dh, bl
mov dl, YEAR_LINE
call show_str
;------------总收入------------
mov ax, es:SUMM_ARRAY[bp] ;低16位
mov dx, es:SUMM_ARRAY[bp + 2] ;高16位
;转换成字符串
call dtoc
;在屏幕上打印
mov dh, bl
mov dl, SUMM_LINE
call show_str
;------------人均收入------------
mov ax, es:SUMM_ARRAY[bp] ;被除数低16位
mov dx, es:SUMM_ARRAY[bp + 2] ;被除数高16位
div word ptr es:COUNT_ARRAY[di] ;除数
mov dx, 0
;转换成字符串
call dtoc
;在屏幕上打印
mov dh, bl
mov dl, AVER_LINE
call show_str
;------------雇员人数------------
mov ax, es:COUNT_ARRAY[di]
mov dx, 0
;转换成字符串
call dtoc
;在屏幕上打印
mov dh, bl
mov dl, COUNT_LINE
call show_str
inc bl
add bp, 4
add di, 2
pop cx
loop output_oneline
;程序无限循环,不会退出,可以直接执行编译生成的文件,看到执行结果。
waitl:
jmp waitl
mov ax, 4c00h
int 21h
;********************************************************************
;名称: show_str
;说明: 在指定的位置,用指定的颜色,显示一个用0结束的字符串
;参数: (dh) = 行号(取值范围0-24),(dl)=列号(取值范围0-79),(cl)=颜色,ds:si指向字符串的首地址
;返回: 无
;********************************************************************
show_str:
push ax
push bx
push cx
push es
push si
mov ax, 0B800H
mov es, ax
;计算缓存首地址
mov bx, 0
mov al, 160
mul dh
add bx, ax
mov al, 2
mul dl
add bx, ax
mov al, cl ;用al缓存颜色
show_byte:
mov cl, ds:[si]
mov ch, 0
jcxz show_str_end
mov es:[bx], cl ;字符
mov es:[bx + 1], al ;颜色
add bx, 2
inc si
jmp show_byte
show_str_end:
pop si
pop es
pop cx
pop bx
pop ax
ret
;********************************************************************
;名称: dtoc
;说明: 将dword型数据转变为表示十进制数的字符串,字符串以0为结尾符
;参数: (ax) = dword型数据低16位
; (dx) = dword型数据高16位
; ds:si指向字符串的首地址
;返回: 无
;********************************************************************
dtoc:
push ax
push bx
push cx
push dx
push di
push si
mov bx, 0 ;累计位数
div_loop:
mov cx, 10 ;除数10
call divdw
push cx ;余数入栈
inc bx
mov cx, ax
or cx, dx ;ax、dx均为0,代表商为0
jcxz end_div ;商为0,结束循环
jmp div_loop
end_div:
mov cx, bx
make_str_loop:
pop dx ;出栈,逆序获取余数,获得字符串
add dl, 30h
mov ds:[si], dl
inc si
loop make_str_loop
mov al, 0
mov ds:[si], al
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret
;********************************************************************
;名称: divdw
;说明: 进行不会溢出的除法运算,被除数DWORD型,除数WORD型,结果DWORD型
;参数: (ax) = dword型数据低16位
; (dx) = dword型数据高16位
; (cx) = 除数
;结果: (ax) = 结果的低16位
; (dx) = 结果的高16位
; (cx) = 余数
;********************************************************************
divdw:
push bx
push ax ;保存被除数低16位L
;计算结果高16位int(H/N) * 65536
mov ax, dx
mov dx, 0
div cx ;结果高16位[int(H/N)]->ax,余数[rem(H/N)]->dx
mov bx, ax ;bx缓存结果高16位
pop ax ;被除数低16位L
div cx ;[rem(H/N)*65536 + L]/N,结果低16位->ax,余数->dx
mov cx, dx ;余数
mov dx, bx ;设置结果高16位
pop bx
ret
codesg ends
end main | | |