鱼C论坛

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

[汇编作业] 课程设计1

[复制链接]
发表于 2020-3-17 22:05:26 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 雪球丶 于 2020-3-17 23:56 编辑
  1. assume cs:code,ss:stack

  2. data segment
  3.         ;data
  4.         db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  5.         db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  6.         db '1993','1994','1995'
  7.         ;21年的字符串
  8.        
  9.         ;data + 54H (84)
  10.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  11.         dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  12.         ;21个年份公司的总收入
  13.        
  14.         ;data + A8H(168)
  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.         ;21个年份的雇员数
  18. data ends

  19. table segment
  20.         ;                        年份 收入 雇员 人均收入
  21.         db 21 dup ('year summ ne ?? ')
  22. table ends

  23. ;创建一个数据段,用来存放格式化之后的数据,用空格填充
  24. ;每行 年份起始索引0,收入起始索引20,雇员数起始索引40,人均收入起始索引60
  25. format segment
  26.         db 1680 dup (' ')
  27.         db 0
  28. format ends

  29. stack segment
  30.         db 128 dup(0)
  31. stack ends

  32. ;将12666以十进制的形式在屏幕的8行3列用绿色显示出来
  33. code segment
  34. start:
  35.                 mov ax,stack
  36.                 mov ss,ax
  37.                 mov sp,128
  38.                
  39.                 mov ax,data
  40.                 mov ds,ax                        ;初始化数据段
  41.                 mov ax,table
  42.                 mov es,ax                        ;es指向table段地址
  43.                
  44.                 ;es指向table段地址
  45.                 call dneat ;整理数据
  46.                
  47.                
  48.                 ;将数据中的数字转换为ascii
  49.                 mov ax,table
  50.                 mov es,ax                ;table段
  51.                 mov ax,format
  52.                 mov ds,ax                ;format段       
  53.                 mov bx,0                ;table行索引
  54.                 mov si,0                ;format行索引
  55.                
  56.                 mov cx,21
  57.         ts:
  58.                 ;拷贝年份数据-字符串(四字节)
  59.                 mov ax,es:[bx]
  60.                 mov ds:[si],ax
  61.                 mov ax,es:[bx+2h]
  62.                 mov ds:[si+2h],ax
  63.                
  64.                 ;将收入转换为ascii的数字(四字节)
  65.                 mov ax,es:[bx+5h]        ;收入低16位
  66.                 mov dx,es:[bx+7h]        ;收入高16位
  67.                 push bx
  68.                 push cx
  69.                 push si
  70.                 add si,20                        ;写到format段每行的第20列处
  71.                 ;函数 dtoc
  72.                 ;将word(16位)型数据转变位标识十进制数的字符串,字符串以0结尾,存放在ds处
  73.                 ;输入参数:
  74.                 ;                (ax) = 32位数字的第16位
  75.                 ;                (dx) = 32位数字的高16位
  76.                 ;                ds:si指向字符串首地址
  77.                 ;返回值: 无
  78.                 call dtoc
  79.                 ;最后一位多多加了一个0,把0去掉,改为空格
  80.                 mov al,20H
  81.                 mov ds:[di],al
  82.                 pop si
  83.                 pop cx
  84.                 pop bx
  85.                
  86.        
  87.                 ;将雇员数改为ascii的数字(2字节)
  88.                 mov ax,es:[bx+0ah]
  89.                 mov dx,0000h
  90.                 push bx
  91.                 push cx
  92.                 push si
  93.                 add si,40                        ;写到format段每行的第40列处
  94.                 call dtoc
  95.                 ;最后一位多多加了一个0,把0去掉,改为空格
  96.                 mov al,20H
  97.                 mov ds:[di],al
  98.                 pop si
  99.                 pop cx
  100.                 pop bx
  101.                
  102.                 ;将平均工资改为ascii的数字(2字节)
  103.                 mov ax,es:[bx+0dh]
  104.                 mov dx,0000h
  105.                 push bx
  106.                 push cx
  107.                 push si
  108.                 add si,60                        ;写到format段每行的第60列处
  109.                 call dtoc
  110.                 ;最后一位多多加了一个0,把0去掉,改为空格
  111.                 mov al,20H
  112.                 mov ds:[di],al
  113.                 pop si
  114.                 pop cx
  115.                 pop bx
  116.                
  117.                 add si,80
  118.                 add bx,16
  119.                 loop ts

  120.                 ;将format段的第22行第一个数据(21x80 + 1= 1681)改为0,作为输出结束标识
  121.                 mov ax,0
  122.                 mov ds:[1681],ax
  123.                
  124.                 ;显示
  125.                 mov dh,1        ;第1行
  126.                 mov dl,0        ;第0列
  127.                 mov cl,2        ;颜色
  128.                 mov ax,format
  129.                 mov ds,ax
  130.                 mov si,0
  131.                 call show_str
  132.                
  133.                 mov ax,4C00H
  134.                 int 21H


  135. ;将word(16位)型数据转变位标识十进制数的字符串,字符串以0结尾,存放在ds处
  136. ;输入参数:
  137. ;                (ax)=word型数据
  138. ;                ds:si指向字符串首地址
  139. ;返回值: 无
  140. ;32位除法所需的寄存器:DX被除数的高16位,AX被除数的低16位,reg,除数(这里是cx)结果:AX商,DX余数
  141. dtoc:        ;mov dx,0000H
  142.                 mov di,si
  143.                 mov bx,0        ;字符长度计数
  144.                 ;输入参数:
  145.                 ;        (ax)=dword型数据的低16位
  146.                 ;        (dx)=dowrd型数据的高16位
  147.                 ;        (cx)=除数
  148.                 ;返回值:
  149.                 ;        (dx)=结果的高16位,(ax)=结果的低16位
  150.                 ;        (cx)=余数
  151.         s0:        mov cx,0AH
  152.                 push bx                                ;divdw函数内部会改变bx的值,把bx暂存起来
  153.                 push si
  154.                 call divdw       
  155.                 pop si
  156.                 pop bx
  157.                 push cx                                ;数据入栈,因为算出来的顺序是反的,所以用栈来倒一下
  158.                 inc bx
  159.                 ;检查商是否为0,为0则计算结束,跳出循环
  160.                 push ax                                ;ax寄存器的值后面还有用,先保存起来
  161.                 or ax,dx
  162.                 mov cx,ax
  163.                 pop ax
  164.                 jcxz s1
  165.                 inc di
  166.                 mov cx,2
  167.                 loop s0
  168.         s1:       
  169.                 mov di,si
  170.                 mov cx,bx
  171.         ens:
  172.                 pop ax
  173.                 add ax,30H                        ;转换为ASCII
  174.                 mov ds:[di],al
  175.                 inc di
  176.                 loop ens
  177.                 mov cl,0                        ;末尾写入0
  178.                 mov ds:[di],cl
  179.                 ret
  180.                
  181. show_str:
  182.                 mov ax,0b800H        ;显存地址
  183.                 mov es,ax
  184.                 ;计算像素点索引 = rowx160 + colx2
  185.                 add dl,dl
  186.                 mov al,dh
  187.                 mov bl,160
  188.                 mul bl                        ;计算出来的行号存储在ax中
  189.                
  190.                 mov dh,0
  191.                 add ax,dx               
  192.                 mov di,ax                ;像素写索引
  193.                 mov dh,cl                ;先用dl记录下颜色值,后面直接用dx寄存器写显存;CX寄存器在循环中会被用到,释放cl
  194.         ws:                                        ;写显存
  195.                 mov dl,ds:[si]
  196.                 mov es:[di],dx
  197.                 inc si
  198.                 add di,2
  199.                 ;查看下一位是否为0
  200.                 mov cx,0
  201.                 mov cl,ds:[si]
  202.                 jcxz wd                        ;若下一位为0,则跳转到wd处
  203.                 mov cx,2                ;给CX赋值,如果程序走到这里说明下一位不为0就让其不断循环继续往下写
  204.                 loop ws
  205.         wd:        ret

  206. divdw:
  207.                 mov si,ax        ;低16位暂存在si中
  208.                 ;计算高16位,将16位计算转化为32位计算
  209.                 mov ax,dx
  210.                 mov dx,0
  211.                 div cx
  212.                 mov bx,ax         ;H/N存放在BX中
  213.                 ;计算低16位
  214.                 mov ax,si
  215.                 div cx
  216.                
  217.                 mov cx,dx
  218.                 mov dx,bx
  219.                 ret
  220.                
  221.                
  222. dneat:
  223.                 mov bx,0                         ;bx作为data段四字节数据的索引 (每次增加4)
  224.                 mov si,0                         ;si作为data段2字节数据的索引 (每次增加2)
  225.                 mov bp,0                        ;bp作为table段的索引 (table每次增加16)
  226.                 mov cx,21
  227. dn_s:       
  228.                 ;拷贝
  229.                 ;table中每年的数据相隔F个字节
  230.                 ;table中同一年数据头索引 year(0)-summ(5)-ne(A)-??(D)
  231.                 ;                        长度(byte)          4       4       2      2       
  232.                 mov ax,ds:[bx]                                ;拷贝年份字符串 4 byte 每次2byte
  233.                 mov es:[bp],ax
  234.                 mov ax,ds:[bx+2H]       
  235.                 mov es:[bp+2H],ax       
  236.                
  237.                 mov ax,ds:[bx+54H]                        ;拷贝收入字符串 dd=4byte 每次2byte
  238.                 mov es:[bp+5H],ax
  239.                 mov ax,ds:[bx+56H]
  240.                 mov es:[bp+5H+2H],ax       
  241.                
  242.                 mov ax,ds:[si+0A8H]       
  243.                 mov es:[bp+0AH],ax                        ;拷贝雇员字符串        dw=2byte
  244.                
  245.                 ;除法计算会改变bx的值,先将bx入栈
  246.                 push bx
  247.                 ;计算平均收入
  248.                 ;load收入(4字节)
  249.                 mov ax,ds:[bx+54H]
  250.                 mov dx,ds:[bx+56H]
  251.                 ;load人数(2字节)
  252.                 mov bx,ds:[si+0A8H]
  253.                 div bx
  254.                
  255.                 ;bx出栈
  256.                 pop bx
  257.                 ;保存计算结果(取整)(2字节)
  258.                 mov es:[bp+0DH],AX
  259.                
  260.                 add bx,4H                       
  261.                 add si,2H
  262.                 add bp,10H                       
  263.                 loop dn_s
  264.                 ret
  265.        
  266. code ends
  267. end start
复制代码


DOS的汇编debug真的太不友好了,调试了三个多小时.....还发现前面几个测试点的程序里面的bug
课设1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-9 17:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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