|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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
-
复制代码
共同点,我都用了较多的栈,去保存函数调用前的数据,所以,我自定义了一个够用的栈。
具体效果,大家自己取执行一下就知道了,我都是按我自己理解做的,和小甲鱼老师答案可能不一样。
最后,再次祝大家,新年快乐,心想事成,万事如意。 |
|