鱼C论坛

 找回密码
 立即注册
查看: 3610|回复: 1

[汇编作业] 汇编语言_课程设计1

[复制链接]
发表于 2021-2-11 23:03:23 | 显示全部楼层 |阅读模式

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

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

x
【交流学习,共同进步】
【大家新年快乐啊!!!恭喜发财,红包拿来!!!!】

下面这个代码我敲了4个小时,头都大了,终于搞定了,不过还是存在很多可以优化的地方,有想法的小伙伴可以试试把我的代码优化一下哦!
还是那句话,我暂时没看小甲鱼老师的答案讲解。因为,只有不看答案,我的结题思路才会是全部原创的,哈哈哈哈。这样做出来的代码,才有更大的交流学习的价值。
  1. assume cs:code, ss:stack

  2. datasg segment
  3.         db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  4.         db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  5.         db '1993','1994','1995'
  6.         ;以上是表示21年的21个字符串,一共84个字节
  7.       
  8.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  9.         dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  10.         ;以上是表示21年公司总收入的21个dword型的数据,一共84个字节
  11.       
  12.         dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  13.         dw 11542,14430,15257,17800
  14.         ;以上是表示21年公司雇员人数的21个word型的数据,一共42个字节
  15. datasg ends

  16. data segment                ;数据段默认用0结尾
  17.     dw 24 dup(0)
  18. data ends

  19. stack segment               ;我用了较多的栈空间,怕溢出,自己定义了一个栈
  20.     dw 32 dup(0)   
  21. stack ends

  22. code segment
  23. start: mov ax,stack           ;初始化栈段
  24.        mov ss,ax
  25.            mov sp,32

  26.            mov ax,data            ;初始化数据段
  27.        mov ds,ax
  28.             
  29.            mov ax,datasg          ;初始化待转化的数据段
  30.            mov es,ax  
  31.           
  32.        mov si,0               ;si记录数据段记录的位置,永远指向结尾的0
  33.            mov di,0               ;di记录待转化数据段的当前转化位置,低指向下一个待转化的地址,0是年份的开始,84是是总收入的起始,168是雇员人数的起始
  34.           
  35.            mov dh,2                ;提前定dh行数
  36.           
  37.           
  38.       
  39.               
  40.            push es                ;置零原先显存上第一页的数据,每一页显存4000个字节,从d8000h开始
  41.            mov ax,0b800h
  42.            mov es,ax
  43.            mov ax,0
  44.        mov cx,2000
  45. clear_gpu:
  46.        mov es:[di],ax
  47.            add di,2;
  48.            loop clear_gpu
  49.            pop es
  50.            mov di,0

  51.            mov cx,21
  52. dfg:   
  53.        push cx
  54.        push dx
  55.        mov si,0          
  56.            mov ax,es:[di]         ;年份转入数据段
  57.            mov ds:[si],ax
  58.            mov ax,es:[di+1]
  59.            mov ds:[si+1],ax
  60.            mov ax,es:[di+2]
  61.            mov ds:[si+2],ax
  62.            mov ax,es:[di+3]
  63.            mov ds:[si+3],ax
  64.          
  65.            mov ax,0                  ;向字符串填入0结尾
  66.            mov ds:[si+4],ax
  67.           
  68.            mov si,0                   ;输出年份
  69.        pop dx
  70.        mov dl,12
  71.        mov cl,2
  72.        call show_str
  73.            push dx
  74.           
  75.            mov ax,es:[di+84]           ;总收入转化成acsell码转入数据段
  76.        mov dx,es:[di+86]
  77.        mov si,12                  ;si指向总收入开始的地址,使其为12   
  78.            call dtoc_plus             ;将ax和dx中的doubleword数据,变成字符串,记录在当前ds:【si】的位置,记录完成后si指向字符串末尾的0

  79.        mov si,12                   ;输出公司总收入
  80.            pop dx
  81.        mov dl,24
  82.        mov cl,2
  83.        call show_str       
  84.        push dx          
  85.           
  86.        mov si,24                   ;si指向总雇员开始的地址,使其为24
  87.           
  88.            push di                            ;di入栈保存,cx入栈保存
  89.            push cx
  90.           
  91.        mov ax,di                           ;使di=二分之一的di
  92.            mov cx,2
  93.            mov dx,0       
  94.            div word ptr cx
  95.            mov di,ax
  96.            mov bp,ax                     ;额外用bp存放二分之一的di
  97.           
  98.            mov ax,es:[di+168]           ;总雇员转化成acsell码转入数据段
  99.        mov dx,0          
  100.            call dtoc_plus             ;将ax和dx中的doubleword数据,变成字符串,记录在当前ds:【si】的位置,记录完成后si指向字符串末尾的0
  101.                      
  102.        pop cx                     ;还原cx与di
  103.            pop di
  104.           
  105.        mov si,24                  ;输出雇员人数
  106.            pop dx
  107.        mov dl,36
  108.        mov cl,2
  109.        call show_str
  110.            push dx
  111.           
  112.            mov ax,es:[di+84]           ;计算人均收入的总收入
  113.        mov dx,es:[di+86]
  114.            mov cx,es:[bp+168]
  115.            div word ptr cx
  116.            mov dx,0
  117.           
  118.            mov si,36                  ;si指向人均收入开始的地址,使其为12   
  119.            call dtoc_plus             ;将ax和dx中的doubleword数据,变成字符串,记录在当前ds:【si】的位置,记录完成后si指向字符串末尾的0
  120.           
  121.            mov si,36                   ;输出人均收入
  122.            pop dx
  123.        mov dl,48
  124.        mov cl,2
  125.        call show_str
  126.                      
  127.           
  128.            add di,4
  129.            add dh,1
  130.            pop cx
  131.            dec cx
  132.            jcxz yui
  133.            jmp dfg
  134.           
  135. yui:  mov ax,4c00h
  136.        int 21h
  137. ;将ax和dx中的doubleword数据用字符串的acsll码,记录在当前ds:【si】的位置,用0做结束,结束时si指向0所在位置
  138. dtoc_plus:
  139.     push dx            ;保留原函数的值
  140.         push cx
  141.         push ax
  142.         push bx

  143.    
  144.         mov bx,0           ;先入栈一个0作为字符串的结尾
  145.         push bx
  146.        
  147. in_stack:             ;处理dword数据的acsll值,并存入栈中
  148.         mov cx,10
  149.     call divdw         ;dx被除数高16位,ax被除数低16位,cx除数,商的高16位在dx,低16位在ax,余数给cx
  150.        
  151.         add cx,30h         ;acsll码值入栈
  152.         push cx
  153.                           
  154.         mov cx,dx          ;双重检查,只有当ax和dx都是0才会通过
  155.         inc cx
  156.         loop in_stack
  157.         mov cx,ax
  158.         inc cx
  159.         loop in_stack
  160.        
  161. out_stack:       
  162.     pop ax             ;栈里面是按word型存储的,但是,因为存进去的数不可能超过8位,所以只有low位有值,取al即可
  163.     mov ds:[si],al
  164.         inc si
  165.     mov cx,ax
  166.         inc cx
  167.     loop out_stack       
  168.     dec si             ;si回去一位,指向0
  169.        

  170.         pop bx
  171.     pop ax
  172.         pop cx
  173.         pop dx
  174.     ret
  175.        
  176. ;dx被除数高16位,ax被除数低16位,cx除数,结果的高16位给dx,低16位给ax,余数给cx          
  177. divdw:  
  178.   push bx         ;保存可能变动的值
  179.   
  180.   push ax
  181.   mov ax, dx ;高16位
  182.   mov dx, 0 ; (新组合的32位的被除数)=0000 000fh
  183.   div cx   ;此时(dx)=余数 和 低16位 组合成一个新的32位的被除数
  184.   mov bx, ax ;结果的高16位
  185.   pop ax   ;低16位
  186.   div cx
  187.   mov cx, dx ;余数
  188.   mov dx, bx ;结果的高16位
  189.   
  190.   pop bx
  191.   ret       
  192. ;将dh看作行号(0-24),dl看作列号(0-79),cl看作颜色,
  193. ;ds:si指向字符串首地址,0为结束的字符串,放入显存指定位置,结束时si指向0所在位置
  194. show_str:
  195.        push ax                 ;因为不知道主函数是否用了ax,先进栈保存,后续会使用ax寄存器
  196.            push di                 ;因为不知道主函数是否用了di,先进栈保存,后续会使用di寄存器
  197.            push es                 ;因为不知道主函数是否用了es,先进栈保存,后续会使用es寄存器
  198.            push cx                 ;后面会对cx改动
  199.            push dx
  200.                      
  201.        mov ax,0b800h           ;显存起始地址给es,用di记录位置
  202.        mov es,ax
  203.                     
  204.            mov di,0
  205.           
  206.            mov al,160              ;每行160个字节,每个字符2个字节,计算字节位置后,给di寄存器
  207.            mul dh
  208.            mov dh,0
  209.            add ax,dx
  210.            add ax,dx
  211.            mov di,ax
  212.           
  213.            mov al,cl                ;写入字符串
  214.            mov ch,0
  215. read_in:
  216.        mov cl,ds:[si]
  217.            jcxz ok      
  218.            mov es:[di],cl
  219.            mov es:[di+1],al
  220.            add di,2
  221.            inc si
  222.            jmp short read_in         
  223.                      
  224. ok:   pop dx
  225.        pop cx   
  226.        pop es
  227.            pop di
  228.            pop ax
  229.        ret           
  230. code ends
  231. end start
  232.        
复制代码

还是发不了图,积分不够,不过我运行过了,是对的哦!
累了,累了,大家加油,好好学习,如果可以的话,帮我刷刷回帖,多顶顶,爱你们哦!

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
weiter + 5 + 5 加油呀,新年快乐!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-3-3 15:45:28 | 显示全部楼层
收藏了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 23:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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