鱼C论坛

 找回密码
 立即注册
查看: 5167|回复: 2

[汇编作业] 汇编语言_实验10(除夕快乐)

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

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

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

x
本帖最后由 635924705 于 2021-2-12 10:58 编辑

【学习交流,共同进步】
正好今天是除夕,给大家拜个年,新年快乐呀,兄弟们!
对了,我做这个实验的时候没看小甲鱼老师的讲解,所以,做法应该会有很大不一样,大家可以看看,一起交流沟通一下。
第一个代码
  1. assume cs:code

  2. data segment
  3.     db 'Welcome to masm!',0
  4.        
  5. data ends

  6. code segment
  7. start: mov dh,8
  8.            mov dl,3
  9.        mov cl,2
  10.        mov ax,data
  11.        mov ds,ax
  12.        mov si,0
  13.        call show_str             
  14.                   
  15.            mov ax,4c00h
  16.        int 21h
  17. ;将dh看作行号(0-24),dl看作列号(0-79),cl看作颜色,
  18. ;ds:si指向字符串首地址,0为结束的字符串,放入显存指定位置,结束时si指向0所在位置
  19. show_str:
  20.        push ax                 ;因为不知道主函数是否用了ax,先进栈保存,后续会使用ax寄存器
  21.            push di                 ;因为不知道主函数是否用了di,先进栈保存,后续会使用di寄存器
  22.            push es                 ;因为不知道主函数是否用了es,先进栈保存,后续会使用es寄存器
  23.            push si                 ;后面会对si改动
  24.            push cx                 ;后面会对cx改动
  25.                      
  26.        mov ax,0b800h           ;显存起始地址给es,用di纪录位置
  27.        mov es,ax
  28.                     
  29.            mov di,0

  30.        push cx                 ;置零原先显存上第一页的数据,每一页显存4000个字节,从d8000h开始
  31.            mov ax,0
  32.        mov cx,2000
  33. clear_gpu:
  34.        mov es:[di],ax
  35.            add di,2;
  36.            loop clear_gpu
  37.            pop cx
  38.           
  39.            mov al,160              ;每行160个字节,每个字符2个字节,计算字节位置后,给di寄存器
  40.            mul dh
  41.            mov dh,0
  42.            add ax,dx
  43.            add ax,dx
  44.            mov di,ax
  45.           
  46.            mov al,cl                ;写入字符串
  47.            mov ch,0
  48. read_in:
  49.        mov cl,ds:[si]
  50.            jcxz ok      
  51.            mov es:[di],cl
  52.            mov es:[di+1],al
  53.            add di,2
  54.            inc si
  55.            jmp short read_in         
  56.                      
  57. ok:   pop cx
  58.        pop si   
  59.        pop es
  60.            pop di
  61.            pop ax
  62.        ret            
  63. code ends
  64. end start
  65.        
复制代码

第二个代码
  1. assume cs:code

  2. code segment
  3. start: mov ax,4240h
  4.            mov dx,000fh
  5.        mov cx,0ah
  6.        call divdw             
  7.                   
  8.            mov ax,4c00h
  9.        int 21h
  10. ;dx被除数高16位,ax被除数低16位,cx除数,结果的高16位给dx,低16位给ax
  11. divdw:  
  12.   push bx         ;保存可能变动的值
  13.   
  14.   push ax
  15.   mov ax, dx ;高16位
  16.   mov dx, 0 ; (新组合的32位的被除数)=0000 000fh
  17.   div cx   ;此时(dx)=余数 和 低16位 组合成一个新的32位的被除数
  18.   mov bx, ax ;结果的高16位
  19.   pop ax   ;低16位
  20.   div cx
  21.   mov cx, dx ;余数
  22.   mov dx, bx ;结果的高16位
  23.   
  24.   pop bx
  25.   ret              
  26. code ends
  27. end start
  28.        
复制代码

第三个代码
  1. assume cs:code, ss:stack

  2. data segment
  3.     dw 24 dup(0)
  4. data ends

  5. datasg segment
  6.     dw 123,12666,1,8,3,38,0 ;用0做结束
  7. datasg ends

  8. stack segment               ;我用了较多的栈空间,怕溢出,自己定义了一个栈
  9.     dw 24 dup(0)   
  10. stack ends

  11. code segment
  12. start: mov ax,stack
  13.        mov ss,ax
  14.            mov sp,32
  15.            mov ax,datasg          ;要处理的数据段用es存放
  16.            mov es,ax
  17.            mov bx,data
  18.        mov ds,bx
  19.           
  20.        mov si,0               ;si记录data段的位置
  21.            mov di,0               ;di记录datasg段的扫描位置
  22.           
  23. qwe:   mov ax,es:[di]
  24.            mov cx,ax
  25.            jcxz jieshu
  26.            inc di
  27.            call dtoc
  28.            mov byte ptr ds:[si],32      ;加空格分割每个word
  29.            inc si                       ;si指向下一个word的开头
  30.            jmp qwe
  31.           
  32. jieshu:
  33.        mov byte ptr ds:[si],0        ;末尾加0,让show_str函数能知道结束位置          
  34.        mov si,0
  35.        mov dh,4
  36.        mov dl,15
  37.        mov cl,2
  38.        call show_str
  39.           
  40.        mov ax,4c00h
  41.        int 21h
  42. ;将ax中的word数据用字符串的acsll码保存在data段偏移地址si开始的位置,用0做结束,结束时si指向0所在位置
  43. dtoc:
  44.     push dx            ;保留原函数的值
  45.         push cx
  46.         push ax
  47.    
  48.         mov dx,0
  49.         push dx
  50. in_stack:              ;先把处理好的acsll值存入栈中
  51.         mov cx,10
  52.     div word ptr cx
  53.         add dx,30h
  54.         push dx
  55.         mov dx,0           ;dx不置零,word除法会报错,我上课可能走神了,一开始没注意到这一点,后面debug一步步查到这错了
  56.         mov cx,ax
  57.         inc cx
  58.         loop in_stack
  59.        
  60. out_stack:       
  61.     pop ax             ;栈里面是按word型存储的,但是,因为存进去的数不可能超过8位,所以只有low位有值,取al即可
  62.     mov ds:[si],al
  63.         inc si
  64.     mov cx,ax
  65.         inc cx
  66.     loop out_stack       
  67.     dec si
  68.        
  69.     pop ax
  70.         pop cx
  71.         pop dx
  72.     ret
  73. ;将dh看作行号(0-24),dl看作列号(0-79),cl看作颜色,
  74. ;ds:si指向字符串首地址,0为结束的字符串,放入显存指定位置,结束时si指向0所在位置
  75. show_str:
  76.        push ax                 ;因为不知道主函数是否用了ax,先进栈保存,后续会使用ax寄存器
  77.            push di                 ;因为不知道主函数是否用了di,先进栈保存,后续会使用di寄存器
  78.            push es                 ;因为不知道主函数是否用了es,先进栈保存,后续会使用es寄存器
  79.            push si                 ;后面会对si改动
  80.            push cx                 ;后面会对cx改动
  81.                      
  82.        mov ax,0b800h           ;显存起始地址给es,用di纪录位置
  83.        mov es,ax
  84.                     
  85.            mov di,0

  86.        push cx                 ;置零原先显存上第一页的数据,每一页显存4000个字节,从d8000h开始
  87.            mov ax,0
  88.        mov cx,2000
  89. clear_gpu:
  90.        mov es:[di],ax
  91.            add di,2;
  92.            loop clear_gpu
  93.            pop cx
  94.           
  95.            mov al,160              ;每行160个字节,每个字符2个字节,计算字节位置后,给di寄存器
  96.            mul dh
  97.            mov dh,0
  98.            add ax,dx
  99.            add ax,dx
  100.            mov di,ax
  101.           
  102.            mov al,cl                ;写入字符串
  103.            mov ch,0
  104. read_in:
  105.        mov cl,ds:[si]
  106.            jcxz ok      
  107.            mov es:[di],cl
  108.            mov es:[di+1],al
  109.            add di,2
  110.            inc si
  111.            jmp short read_in         
  112.                      
  113. ok:   pop cx
  114.        pop si   
  115.        pop es
  116.            pop di
  117.            pop ax
  118.        ret           
  119. code ends
  120. end start
  121.        
复制代码

共同点,我都用了较多的栈,去保存函数调用前的数据,所以,我自定义了一个够用的栈。
具体效果,大家自己取执行一下就知道了,我都是按我自己理解做的,和小甲鱼老师答案可能不一样。
最后,再次祝大家,新年快乐,心想事成,万事如意。

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-3-24 19:13:34 | 显示全部楼层
3中的     div word ptr cx 这条应该是错误的吧  在没有寄存器名的情况下 才用操作符 word ptr 指明内存单元的长度 你这个后面直接跟一个寄存器名 应该是报错的啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-3-24 23:53:32 | 显示全部楼层
qq904641971 发表于 2021-3-24 19:13
3中的     div word ptr cx 这条应该是错误的吧  在没有寄存器名的情况下 才用操作符 word ptr 指明内存单 ...

完全没问题啊
B5O[%EI%R0H$LM{Q~711[U2.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-8 09:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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