|
主题 : : 第10章 课程设计1 实现代码 应该是最简洁的代码了 [待解决] |
回复[ 3次 ]
点击[ 636次 ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-02 12:37 |
assume cs:code, ds:data, ss:stack
data segment
db '1975', '1976', '1977', '1978', '1979', '1980', '1981'
db '1982', '1983', '1984', '1985', '1986', '1987', '1988'
db '1989', '1990', '1991', '1992', '1993', '1994', '1995'
dd 16, 22, 382, 1356, 2390, 8000, 16000
dd 24486, 50065, 97479, 140417, 197514, 345980, 590827
dd 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000
dw 3, 7, 9, 13, 28, 38, 130
dw 220, 476, 778, 1001, 1442, 2258, 2793
dw 4037, 5635, 8226, 11542, 14430, 15257, 17800
data ends
buffer segment
db 010h dup (0)
buffer ends
stack segment
db 040h dup (0)
stack ends
code segment
start:
mov ax, data ; 使ds指向data
mov ds, ax
mov ax, stack ; 使ss指向stack
mov ss, ax
mov sp, 040h
mov di, 0 ; di可寻址雇员数
mov bh, 4 ; 设定打印的起始行号
mov cx, 21 ; 设定循环次数
again:
mov si, di ; 下标di乘以2后存入si
add si, si ; si可寻址年份和收入
push cx ; 显示年份
mov al, ds:[si].4
mov byte ptr ds:[si].4, 0
mov dh, bh
mov dl, 0
mov cl, 00001100B
call show_string
mov ds:[si].4, al
pop cx
mov ax, ds:054h[si].0 ; 显示收入
mov dx, ds:054h[si].2
mov bl, 12
call show_dword
mov bp, ds:0a8h[di] ; 雇员数保存在bp里
div bp ; 显示平均工资
mov dx, 0
mov bl, 36
call show_dword
mov ax, bp ; 显示雇员数
mov bl, 24
call show_dword
inc bh ; 继续处理下一组数据
add di, 02h
loop again
mov ax, 04c00h ; 程序退出
int 021h
;--------------------------------------------------------
; 功能 - 以字符串形式显示dword型数据
; 参数 - (dx) = dword的高16位
; (ax) = dword的低16位
; (bh) = 行号(取值范围0-24)
; (bl) = 列号(取值范围0-79)
; 返回 - 无
;--------------------------------------------------------
show_dword:
push ds
push cx
push dx
push si
mov cx, buffer
mov ds, cx
mov si, 0
call dword_to_string ; dword转换后存入buffer
mov dx, bx
mov cl, 00001100B
call show_string ; 显示转换后的字符串
pop si
pop dx
pop cx
pop ds
ret
;--------------------------------------------------------
; 功能 - 将dword转换成十进制的字符串 字符串以0结尾
; 参数 - (dx) = dword的高16位
; (ax) = dword的低16位
; (ds:si) = 接收字符串的缓冲
; 返回 - 无
;--------------------------------------------------------
dword_to_string:
push ax
push cx
push dx
push si
mov cx, 0 ; 在栈里设置一个循环出栈时的结束标志
push cx ; 当遇见这个标志时正好结束循环出栈
; 而这个标志正好做了字符串的结束符
dword_to_string_push:
mov cx, 0ah ; dword循环除以10
call safe_div
add cl, '0' ; 余数直接转换为ASCII码的十进制
push cx ; 保存进堆栈
mov cx, dx ; 如果商是0则转换完毕
or cx, ax
jcxz dword_to_string_pop
jmp dword_to_string_push
dword_to_string_pop: ; 字符循环出栈 遇到0结束
pop cx
mov ds:[si], cl
jcxz dword_to_string_done
inc si
jmp dword_to_string_pop
dword_to_string_done:
pop si
pop dx
pop cx
pop ax
ret
;--------------------------------------------------------
; 功能 - 进行不会产生溢出的除法运算
; 参数 - (dx) = dword型数据的高16位
; (ax) = dword型数据的低16位
; (cx) = 除数
; 返回 - (dx) = 结果的高16位
; (ax) = 结果的低16位
; (cx) = 余数
;--------------------------------------------------------
safe_div:
push bx
push ax
mov ax, dx
mov dx, 0
div cx
mov bx, ax
pop ax
div cx
mov cx, dx
mov dx, bx
pop bx
ret
;--------------------------------------------------------
; 功能 - 在指定的位置 用指定的颜色 显示一个用0结束的字符串
; 参数 - (dh) = 行号(取值范围0-24)
; (dl) = 列号(取值范围0-79)
; (cl) = 颜色
; (ds:si) = 字符串首地址
; 返回 - 无
;--------------------------------------------------------
show_string:
push es
push ax
push cx
push si
push di
mov ax, 0b800h ; 使es指向视频段
mov es, ax
mov al, 0a0h ; 计算向视频段的写入地址di
mul dh ; di = (dh * 80 + dl) * 2
mov di, ax
mov al, 2
mul dl
add di, ax
mov ah, cl
mov ch, 0
show_string_copy:
mov cl, ds:[si]
jcxz show_string_done
mov al, cl
mov es:[di], ax
inc si
add di, 2
jmp show_string_copy
show_string_done:
pop di
pop si
pop cx
pop ax
pop es
ret
code ends
end start | | |