635924705 发表于 2021-2-11 12:25:50

汇编语言_实验10(除夕快乐)

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

【学习交流,共同进步】
正好今天是除夕,给大家拜个年,新年快乐呀,兄弟们!{:10_279:}
对了,我做这个实验的时候没看小甲鱼老师的讲解,所以,做法应该会有很大不一样,大家可以看看,一起交流沟通一下。{:10_327:}
第一个代码
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:,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:
           jcxz ok      
           mov es:,cl
           mov es:,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:
           mov cx,ax
           jcxz jieshu
           inc di
           call dtoc
           mov byte ptr ds:,32      ;加空格分割每个word
           inc si                     ;si指向下一个word的开头
           jmp qwe
          
jieshu:
       mov byte ptr ds:,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:,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:,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:
           jcxz ok      
           mov es:,cl
           mov es:,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
       
共同点,我都用了较多的栈,去保存函数调用前的数据,所以,我自定义了一个够用的栈。
具体效果,大家自己取执行一下就知道了,我都是按我自己理解做的,和小甲鱼老师答案可能不一样。
最后,再次祝大家,新年快乐,心想事成,万事如意。

qq904641971 发表于 2021-3-24 19:13:34

3中的   div word ptr cx 这条应该是错误的吧在没有寄存器名的情况下 才用操作符 word ptr 指明内存单元的长度 你这个后面直接跟一个寄存器名 应该是报错的啊

635924705 发表于 2021-3-24 23:53:32

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

完全没问题啊
页: [1]
查看完整版本: 汇编语言_实验10(除夕快乐)