汇编语言_实验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
共同点,我都用了较多的栈,去保存函数调用前的数据,所以,我自定义了一个够用的栈。
具体效果,大家自己取执行一下就知道了,我都是按我自己理解做的,和小甲鱼老师答案可能不一样。
最后,再次祝大家,新年快乐,心想事成,万事如意。 3中的 div word ptr cx 这条应该是错误的吧在没有寄存器名的情况下 才用操作符 word ptr 指明内存单元的长度 你这个后面直接跟一个寄存器名 应该是报错的啊 qq904641971 发表于 2021-3-24 19:13
3中的 div word ptr cx 这条应该是错误的吧在没有寄存器名的情况下 才用操作符 word ptr 指明内存单 ...
完全没问题啊
页:
[1]