鱼C论坛

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

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

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

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

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

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

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

data segment
    db 'Welcome to masm!',0
        
data ends

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

       push cx                 ;置零原先显存上第一页的数据,每一页显存4000个字节,从d8000h开始
           mov ax,0
       mov cx,2000
clear_gpu:
       mov es:[di],ax
           add di,2;
           loop clear_gpu
           pop cx
           
           mov al,160              ;每行160个字节,每个字符2个字节,计算字节位置后,给di寄存器
           mul dh
           mov dh,0
           add ax,dx
           add ax,dx
           mov di,ax
           
           mov al,cl                ;写入字符串
           mov ch,0
read_in:
       mov cl,ds:[si]
           jcxz ok      
           mov es:[di],cl
           mov es:[di+1],al
           add di,2
           inc si
           jmp short read_in         
                      
 ok:   pop cx
       pop si   
       pop es
           pop di
           pop ax
       ret             
code ends
end start
        
第二个代码
assume cs:code

code segment
start: mov ax,4240h
           mov dx,000fh
       mov cx,0ah
       call divdw              
                  
           mov ax,4c00h
       int 21h
;dx被除数高16位,ax被除数低16位,cx除数,结果的高16位给dx,低16位给ax
divdw:  
  push bx         ;保存可能变动的值
  
  push ax
  mov ax, dx ;高16位
  mov dx, 0 ; (新组合的32位的被除数)=0000 000fh
  div cx   ;此时(dx)=余数 和 低16位 组合成一个新的32位的被除数
  mov bx, ax ;结果的高16位
  pop ax   ;低16位
  div cx
  mov cx, dx ;余数
  mov dx, bx ;结果的高16位
  
  pop bx
  ret               
code ends
end start
        
第三个代码
assume cs:code, ss:stack

data segment
    dw 24 dup(0)
data ends

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

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

code segment
start: mov ax,stack
       mov ss,ax
           mov sp,32
           mov ax,datasg          ;要处理的数据段用es存放
           mov es,ax
           mov bx,data
       mov ds,bx
           
       mov si,0               ;si记录data段的位置
           mov di,0               ;di记录datasg段的扫描位置
           
qwe:   mov ax,es:[di]
           mov cx,ax
           jcxz jieshu 
           inc di
           call dtoc
           mov byte ptr ds:[si],32      ;加空格分割每个word
           inc si                       ;si指向下一个word的开头
           jmp qwe
           
jieshu:
       mov byte ptr ds:[si],0        ;末尾加0,让show_str函数能知道结束位置           
       mov si,0
       mov dh,4
       mov dl,15
       mov cl,2
       call show_str
           
       mov ax,4c00h
       int 21h
;将ax中的word数据用字符串的acsll码保存在data段偏移地址si开始的位置,用0做结束,结束时si指向0所在位置
dtoc:
    push dx            ;保留原函数的值
        push cx
        push ax
    
        mov dx,0
        push dx
in_stack:              ;先把处理好的acsll值存入栈中
        mov cx,10
    div word ptr cx
        add dx,30h
        push dx
        mov dx,0           ;dx不置零,word除法会报错,我上课可能走神了,一开始没注意到这一点,后面debug一步步查到这错了
        mov cx,ax
        inc cx
        loop in_stack
        
out_stack:        
    pop ax             ;栈里面是按word型存储的,但是,因为存进去的数不可能超过8位,所以只有low位有值,取al即可
    mov ds:[si],al
        inc si
    mov cx,ax
        inc cx
    loop out_stack        
    dec si
        
    pop ax
        pop cx
        pop dx
    ret
;将dh看作行号(0-24),dl看作列号(0-79),cl看作颜色,
;ds:si指向字符串首地址,0为结束的字符串,放入显存指定位置,结束时si指向0所在位置
show_str:
       push ax                 ;因为不知道主函数是否用了ax,先进栈保存,后续会使用ax寄存器
           push di                 ;因为不知道主函数是否用了di,先进栈保存,后续会使用di寄存器
           push es                 ;因为不知道主函数是否用了es,先进栈保存,后续会使用es寄存器
           push si                 ;后面会对si改动
           push cx                 ;后面会对cx改动
                      
       mov ax,0b800h           ;显存起始地址给es,用di纪录位置
       mov es,ax
                     
           mov di,0

       push cx                 ;置零原先显存上第一页的数据,每一页显存4000个字节,从d8000h开始
           mov ax,0
       mov cx,2000
clear_gpu:
       mov es:[di],ax
           add di,2;
           loop clear_gpu
           pop cx
           
           mov al,160              ;每行160个字节,每个字符2个字节,计算字节位置后,给di寄存器
           mul dh
           mov dh,0
           add ax,dx
           add ax,dx
           mov di,ax
           
           mov al,cl                ;写入字符串
           mov ch,0
read_in:
       mov cl,ds:[si]
           jcxz ok      
           mov es:[di],cl
           mov es:[di+1],al
           add di,2
           inc si
           jmp short read_in         
                      
 ok:   pop cx
       pop si   
       pop es
           pop di
           pop ax
       ret            
code ends
end start
        
共同点,我都用了较多的栈,去保存函数调用前的数据,所以,我自定义了一个够用的栈。
具体效果,大家自己取执行一下就知道了,我都是按我自己理解做的,和小甲鱼老师答案可能不一样。
最后,再次祝大家,新年快乐,心想事成,万事如意。

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2021-3-24 19:13:34 | 显示全部楼层
3中的     div word ptr cx 这条应该是错误的吧  在没有寄存器名的情况下 才用操作符 word ptr 指明内存单元的长度 你这个后面直接跟一个寄存器名 应该是报错的啊
想知道小甲鱼最近在做啥?请访问 -> 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-27 21:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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