|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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:代码比较乱。。。涉及的寄存器通通入栈,所以栈空间也开了比较大
|
|