鱼C论坛

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

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

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

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

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

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

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

  1. assume cs:code,ds:data

  2. ; 字符串临时区
  3. string segment
  4.                 db 16 dup(0)
  5. string ends

  6. ; 源数据
  7. data segment
  8.                 db '1975',0,'1976',0,'1977',0,'1978',0,'1979',0,'1980',0,'1981',0,'1982',0,'1983',0
  9.                 db '1984',0,'1985',0,'1986',0,'1987',0,'1988',0,'1989',0,'1990',0,'1991',0,'1992',0
  10.                 db '1993',0,'1994',0,'1995',0
  11.                
  12.                 dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  13.                 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  14.                
  15.                 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  16.                 dw 11542,14430,15257,17800
  17. data ends

  18. ; 栈
  19. stack segment stack
  20.                 dw 32 dup(0)
  21. stack ends

  22. code segment
  23. start:        mov bp, sp
  24.                 sub sp, 16 ; 划分出16字节的变量区
  25.                
  26.                 mov word ptr ss:[bp - 2], 0                        ; 年份的指针
  27.                 mov word ptr ss:[bp - 4], 0                        ; 总收入的指针
  28.                 mov word ptr ss:[bp - 6], 0                        ; 雇员数的指针
  29.                 mov word ptr ss:[bp - 8], 100h                  ; 记录行和列
  30.                
  31.                 mov cx, 21
  32. mainloop:
  33.                 call draw
  34.                 loop mainloop
  35.                
  36.                 mov ax, 4c00h
  37.                 int 21h
  38.                
  39. draw:        ; 绘制子函数
  40.                 push ax
  41.                 push bx
  42.                 push cx
  43.                 push dx
  44.                 push si
  45.                 push di
  46.                 push ds
  47.                 push es
  48.                
  49.                 ; ---------------------------
  50.                 ; 输出3个字符的空格
  51.                 mov ax, string
  52.                 mov ds, ax
  53.                 mov si, 15
  54.                 mov cx, 317h                ; 设定颜色与宽度
  55.                 mov dx, ss:[bp - 8]
  56.                 call show_str
  57.                
  58.                 ; ---------------------------
  59.                 ; 输出年份
  60.                 mov ax, data
  61.                 mov ds, ax
  62.                 mov es, ax
  63.                 mov si, ss:[bp - 2]
  64.                 mov cx, 0a17h                ; 设定颜色与宽度
  65.                 add byte ptr ss:[bp - 8], 3
  66.                 mov dx, ss:[bp - 8]
  67.                 call show_str
  68.                 ; 指向下一个年份
  69.                 add word ptr ss:[bp - 2], 5
  70.                
  71.                 ; ---------------------------
  72.                 ; 输出总收入
  73.                 mov ax, string
  74.                 mov ds, ax
  75.                 mov bx, ss:[bp - 4]
  76.                 mov ax, es:[bx + 21 * 5]
  77.                 mov dx, es:[bx + 21 * 5 + 2]
  78.                 xor di, di
  79.                 call dwtoc
  80.                
  81.                 push dx; 保存总收入高16位
  82.                
  83.                 mov si, di
  84.                 mov cx, 0a20h
  85.                 add byte ptr ss:[bp - 8], 10
  86.                 mov dx, ss:[bp - 8]
  87.                 call show_str
  88.                 ; 指向下一个总收入
  89.                 add word ptr ss:[bp - 4], 4
  90.                
  91.                 ; ---------------------------
  92.                 ; 输出雇员数
  93.                 push ax                ; 保存总收入低16位
  94.                
  95.                 mov bx, ss:[bp - 6]
  96.                 mov ax, es:[bx + 21 * (4 + 5)]
  97.                 xor dx, dx
  98.                 xor di, di
  99.                 call dwtoc
  100.                
  101.                 mov si, di
  102.                 mov cx, 0a30h
  103.                 add byte ptr ss:[bp - 8], 10
  104.                 mov dx, ss:[bp - 8]
  105.                 call show_str
  106.                
  107.                 mov cx, ax
  108.                
  109.                 pop ax
  110.                 pop dx
  111.                 ; 指向下一个雇员数
  112.                 add word ptr ss:[bp - 6], 2
  113.                
  114.                 ; ---------------------------
  115.                 ; 计算并输出人均收入
  116.                 call divdw
  117.                
  118.                 xor di, di
  119.                 call dwtoc
  120.                
  121.                 mov si, di
  122.                 mov cx, 0a47h                ; 设定颜色与宽度
  123.                 add byte ptr ss:[bp - 8], 10
  124.                 mov dx, ss:[bp - 8]
  125.                 call show_str
  126.                
  127.                 ; ---------------------------
  128.                 ; 清除后面的字符
  129.                 mov si, 15
  130.                 mov cx, 2507h                ; 设定颜色与宽度
  131.                 add byte ptr ss:[bp - 8], 10
  132.                 mov dx, ss:[bp - 8]
  133.                 call show_str
  134.                
  135.                 ; ---------------------------
  136.                 ; 转入下一行
  137.                 add byte ptr ss:[bp - 7], 1
  138.                 mov byte ptr ss:[bp - 8], 0
  139.                
  140.                 pop es
  141.                 pop ds
  142.                 pop di
  143.                 pop si
  144.                 pop dx
  145.                 pop cx
  146.                 pop bx
  147.                 pop ax
  148.                 ret
  149.                
  150.                 ; ==============================
  151.                 ; 整型(32位)转为字符型
  152.                 ; 结果:di
  153.                 ; 源数据低16位:ax
  154.                 ; 源数据高16位:dx
  155.                 ; ==============================
  156. dwtoc:        push dx
  157.                 push cx
  158.                 push bx
  159.                 push ax
  160.                
  161.                 add di, 14
  162. nextnum:
  163.                 mov cx, 10
  164.                 call divdw
  165.                
  166.                 add cx, 30h
  167.                 mov [di], cl
  168.                
  169.                 ; 判断是否已经除尽
  170.                 or ax, dx
  171.                 mov cx, ax
  172.                 jcxz end_dtoc
  173.                
  174.                 ; 在尚未统计完所有数码时,才前移指针
  175.                 dec di
  176.                 jmp short nextnum

  177. end_dtoc:
  178.                 pop ax
  179.                 pop bx
  180.                 pop cx
  181.                 pop dx
  182.                 ret
  183.                
  184.                 ; ==============================
  185.                 ; 在指定位置显示字符串(去掉指定宽度的字符)
  186.                 ; 源字串:si
  187.                 ; 行数:dh(0~24)
  188.                 ; 列数:dl(0~79)
  189.                 ; 颜色:cl
  190.                 ; 每个数据的宽度:ch
  191.                 ; ==============================
  192. show_str:
  193.                 push bp
  194.                 mov bp, sp
  195.                
  196.                 push cx
  197.                 push bx
  198.                 push ax
  199.                 push dx
  200.                 push si
  201.                 push di
  202.                 push es
  203.                
  204.                 mov ax, 0b800h
  205.                 mov es, ax                        ; 定位段地址
  206.                
  207.                 mov ax, 160
  208.                 mul dh                                        ; 定位行数
  209.                 mov di, ax
  210.                 xor dh, dh
  211.                 add dx, dx
  212.                 add di, dx

  213.                 ; 开始复制了
  214.                 xor ch, ch
  215.                 ; 计算字符串的长度
  216.                 xor bx, bx
  217. copy_oneword:
  218.                 mov cl, [si]
  219.                 jcxz return
  220.                
  221.                 mov es:[di], cl
  222.                 inc di
  223.                 mov al, [bp - 2]
  224.                 mov es:[di], al
  225.                 inc di
  226.                 inc si
  227.                 inc bx
  228.                 jmp short copy_oneword
  229.                
  230. return:     ; 在返回前,判断是否超出了规定的宽度
  231.                 ; 如果超出了,直接返回
  232.                 ; 如果没有超出,那么还得填充空格
  233.                 mov cl, [bp - 1]
  234.                 xor ch, ch
  235.                 cmp cx, bx
  236.                 jng popstack
  237.                
  238.                 sub cx, bx
  239. clear_after:
  240.                 mov byte ptr es:[di], 0
  241.                 mov al, [bp - 2]
  242.                 mov es:[di + 1], al
  243.                 add di, 2
  244.                 loop clear_after

  245. popstack:
  246.                 pop es
  247.                 pop di
  248.                 pop si
  249.                 pop dx
  250.                 pop ax
  251.                 pop bx
  252.                 pop cx
  253.                
  254.                 pop bp
  255.                 ret
  256.                
  257.                 ; ==============================
  258.                 ; 32位/16位不溢出除法
  259.                 ; ax:被除数低16位(商低16位)
  260.                 ; dx:被除数高16位(商高16位)
  261.                 ; cx:除数(余数)
  262.                 ; ==============================
  263. divdw:     push bx
  264.                 mov bx, ax                ; 被除数低16位
  265.                
  266.                 ; int(H/N)
  267.                 mov ax, dx
  268.                 xor dx, dx
  269.                 div cx                ; 结果在ax中,余数在dx中
  270.                 push ax                ; 保存的是H/N的结果
  271.                
  272.                 ; (rem(H/N) * 65536 + L) / N
  273.                 mov ax, bx
  274.                 div cx
  275.                 mov cx, dx                ; 余数得到了
  276.                
  277.                 ; int(H/N) * 65536
  278.                 pop dx                ; 结果高16位
  279.                
  280.                 pop bx
  281.                 ret
  282.                
  283. code ends

  284. end start
复制代码

结果

结果



ps:代码比较乱。。。涉及的寄存器通通入栈,所以栈空间也开了比较大
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-20 01:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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