南郊居士 发表于 2015-5-18 10:24:34

课程设计1炫彩版

“炫彩”只是假象。。。

我的目的是将表格做得更像表格:在输出函数中添加了一个参数用来控制输出宽度,这样就可以实现(半)自动对齐
所谓“炫彩”是对齐的附属物,用来检查对齐是否生效

assume cs:code,ds:data

; 字符串临时区
string segment
                db 16 dup(0)
string ends

; 源数据
data segment
                db '1975',0,'1976',0,'1977',0,'1978',0,'1979',0,'1980',0,'1981',0,'1982',0,'1983',0
                db '1984',0,'1985',0,'1986',0,'1987',0,'1988',0,'1989',0,'1990',0,'1991',0,'1992',0
                db '1993',0,'1994',0,'1995',0
               
                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
data ends

; 栈
stack segment stack
                dw 32 dup(0)
stack ends

code segment
start:      mov bp, sp
                sub sp, 16 ; 划分出16字节的变量区
               
                mov word ptr ss:, 0                        ; 年份的指针
                mov word ptr ss:, 0                        ; 总收入的指针
                mov word ptr ss:, 0                        ; 雇员数的指针
                mov word ptr ss:, 100h                  ; 记录行和列
               
                mov cx, 21
mainloop:
                call draw
                loop mainloop
               
                mov ax, 4c00h
                int 21h
               
draw:      ; 绘制子函数
                push ax
                push bx
                push cx
                push dx
                push si
                push di
                push ds
                push es
               
                ; ---------------------------
                ; 输出3个字符的空格
                mov ax, string
                mov ds, ax
                mov si, 15
                mov cx, 317h                ; 设定颜色与宽度
                mov dx, ss:
                call show_str
               
                ; ---------------------------
                ; 输出年份
                mov ax, data
                mov ds, ax
                mov es, ax
                mov si, ss:
                mov cx, 0a17h                ; 设定颜色与宽度
                add byte ptr ss:, 3
                mov dx, ss:
                call show_str
                ; 指向下一个年份
                add word ptr ss:, 5
               
                ; ---------------------------
                ; 输出总收入
                mov ax, string
                mov ds, ax
                mov bx, ss:
                mov ax, es:
                mov dx, es:
                xor di, di
                call dwtoc
               
                push dx; 保存总收入高16位
               
                mov si, di
                mov cx, 0a20h
                add byte ptr ss:, 10
                mov dx, ss:
                call show_str
                ; 指向下一个总收入
                add word ptr ss:, 4
               
                ; ---------------------------
                ; 输出雇员数
                push ax                ; 保存总收入低16位
               
                mov bx, ss:
                mov ax, es:
                xor dx, dx
                xor di, di
                call dwtoc
               
                mov si, di
                mov cx, 0a30h
                add byte ptr ss:, 10
                mov dx, ss:
                call show_str
               
                mov cx, ax
               
                pop ax
                pop dx
                ; 指向下一个雇员数
                add word ptr ss:, 2
               
                ; ---------------------------
                ; 计算并输出人均收入
                call divdw
               
                xor di, di
                call dwtoc
               
                mov si, di
                mov cx, 0a47h                ; 设定颜色与宽度
                add byte ptr ss:, 10
                mov dx, ss:
                call show_str
               
                ; ---------------------------
                ; 清除后面的字符
                mov si, 15
                mov cx, 2507h                ; 设定颜色与宽度
                add byte ptr ss:, 10
                mov dx, ss:
                call show_str
               
                ; ---------------------------
                ; 转入下一行
                add byte ptr ss:, 1
                mov byte ptr ss:, 0
               
                pop es
                pop ds
                pop di
                pop si
                pop dx
                pop cx
                pop bx
                pop ax
                ret
               
                ; ==============================
                ; 整型(32位)转为字符型
                ; 结果:di
                ; 源数据低16位:ax
                ; 源数据高16位:dx
                ; ==============================
dwtoc:      push dx
                push cx
                push bx
                push ax
               
                add di, 14
nextnum:
                mov cx, 10
                call divdw
               
                add cx, 30h
                mov , cl
               
                ; 判断是否已经除尽
                or ax, dx
                mov cx, ax
                jcxz end_dtoc
               
                ; 在尚未统计完所有数码时,才前移指针
                dec di
                jmp short nextnum

end_dtoc:
                pop ax
                pop bx
                pop cx
                pop dx
                ret
               
                ; ==============================
                ; 在指定位置显示字符串(去掉指定宽度的字符)
                ; 源字串:si
                ; 行数:dh(0~24)
                ; 列数:dl(0~79)
                ; 颜色:cl
                ; 每个数据的宽度:ch
                ; ==============================
show_str:
                push bp
                mov bp, sp
               
                push cx
                push bx
                push ax
                push dx
                push si
                push di
                push es
               
                mov ax, 0b800h
                mov es, ax                        ; 定位段地址
               
                mov ax, 160
                mul dh                                        ; 定位行数
                mov di, ax
                xor dh, dh
                add dx, dx
                add di, dx

                ; 开始复制了
                xor ch, ch
                ; 计算字符串的长度
                xor bx, bx
copy_oneword:
                mov cl,
                jcxz return
               
                mov es:, cl
                inc di
                mov al,
                mov es:, al
                inc di
                inc si
                inc bx
                jmp short copy_oneword
               
return:   ; 在返回前,判断是否超出了规定的宽度
                ; 如果超出了,直接返回
                ; 如果没有超出,那么还得填充空格
                mov cl,
                xor ch, ch
                cmp cx, bx
                jng popstack
               
                sub cx, bx
clear_after:
                mov byte ptr es:, 0
                mov al,
                mov es:, al
                add di, 2
                loop clear_after

popstack:
                pop es
                pop di
                pop si
                pop dx
                pop ax
                pop bx
                pop cx
               
                pop bp
                ret
               
                ; ==============================
                ; 32位/16位不溢出除法
                ; ax:被除数低16位(商低16位)
                ; dx:被除数高16位(商高16位)
                ; cx:除数(余数)
                ; ==============================
divdw:   push bx
                mov bx, ax                ; 被除数低16位
               
                ; int(H/N)
                mov ax, dx
                xor dx, dx
                div cx                ; 结果在ax中,余数在dx中
                push ax                ; 保存的是H/N的结果
               
                ; (rem(H/N) * 65536 + L) / N
                mov ax, bx
                div cx
                mov cx, dx                ; 余数得到了
               
                ; int(H/N) * 65536
                pop dx                ; 结果高16位
               
                pop bx
                ret
               
code ends

end start



ps:代码比较乱。。。涉及的寄存器通通入栈,所以栈空间也开了比较大
页: [1]
查看完整版本: 课程设计1炫彩版