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