鱼C论坛

 找回密码
 立即注册
查看: 2208|回复: 0

[汇编作业] 课程设计1炫彩版

[复制链接]
发表于 2015-5-18 10:24:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
“炫彩”只是假象。。。

我的目的是将表格做得更像表格:在输出函数中添加了一个参数用来控制输出宽度,这样就可以实现(半)自动对齐
所谓“炫彩”是对齐的附属物,用来检查对齐是否生效
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:[bp - 2], 0                        ; 年份的指针
                mov word ptr ss:[bp - 4], 0                        ; 总收入的指针
                mov word ptr ss:[bp - 6], 0                        ; 雇员数的指针
                mov word ptr ss:[bp - 8], 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:[bp - 8]
                call show_str
                
                ; ---------------------------
                ; 输出年份
                mov ax, data
                mov ds, ax
                mov es, ax
                mov si, ss:[bp - 2]
                mov cx, 0a17h                ; 设定颜色与宽度
                add byte ptr ss:[bp - 8], 3
                mov dx, ss:[bp - 8]
                call show_str
                ; 指向下一个年份
                add word ptr ss:[bp - 2], 5
                
                ; ---------------------------
                ; 输出总收入
                mov ax, string
                mov ds, ax
                mov bx, ss:[bp - 4]
                mov ax, es:[bx + 21 * 5]
                mov dx, es:[bx + 21 * 5 + 2]
                xor di, di
                call dwtoc
                
                push dx; 保存总收入高16位
                
                mov si, di
                mov cx, 0a20h
                add byte ptr ss:[bp - 8], 10
                mov dx, ss:[bp - 8]
                call show_str
                ; 指向下一个总收入
                add word ptr ss:[bp - 4], 4
                
                ; ---------------------------
                ; 输出雇员数
                push ax                ; 保存总收入低16位
                
                mov bx, ss:[bp - 6]
                mov ax, es:[bx + 21 * (4 + 5)]
                xor dx, dx
                xor di, di
                call dwtoc
                
                mov si, di
                mov cx, 0a30h
                add byte ptr ss:[bp - 8], 10
                mov dx, ss:[bp - 8]
                call show_str
                
                mov cx, ax
                
                pop ax
                pop dx
                ; 指向下一个雇员数
                add word ptr ss:[bp - 6], 2
                
                ; ---------------------------
                ; 计算并输出人均收入
                call divdw
                
                xor di, di
                call dwtoc
                
                mov si, di
                mov cx, 0a47h                ; 设定颜色与宽度
                add byte ptr ss:[bp - 8], 10
                mov dx, ss:[bp - 8]
                call show_str
                
                ; ---------------------------
                ; 清除后面的字符
                mov si, 15
                mov cx, 2507h                ; 设定颜色与宽度
                add byte ptr ss:[bp - 8], 10
                mov dx, ss:[bp - 8]
                call show_str
                
                ; ---------------------------
                ; 转入下一行
                add byte ptr ss:[bp - 7], 1
                mov byte ptr ss:[bp - 8], 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 [di], 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, [si]
                jcxz return
                
                mov es:[di], cl
                inc di
                mov al, [bp - 2]
                mov es:[di], al
                inc di
                inc si
                inc bx
                jmp short copy_oneword
                
return:     ; 在返回前,判断是否超出了规定的宽度
                ; 如果超出了,直接返回
                ; 如果没有超出,那么还得填充空格
                mov cl, [bp - 1]
                xor ch, ch
                cmp cx, bx
                jng popstack
                
                sub cx, bx
clear_after:
                mov byte ptr es:[di], 0
                mov al, [bp - 2]
                mov es:[di + 1], 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:代码比较乱。。。涉及的寄存器通通入栈,所以栈空间也开了比较大
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-27 16:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表