实验10 编写子程序
本帖最后由 流风逸雪 于 2020-4-11 16:14 编辑1.显示字符串
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
call show_str
mov si,0
mov ax,4c00H
int 21h
show_str:;借用实验9的代码
mov al,dh
mov bl,160
mul bl
add dl,dl;显存的奇数字节为字的内容,偶数为字的外观属性,所以要列地址*2作为显存地址
add al,dl
mov di,ax
mov bx,0
mov ax,0B800H;显存位置
mov es,ax
mov ah,cl
mov cx,16
s: mov al,
mov es:,al
inc bx
inc di
mov es:,ah
inc di
loop s
ret
code ends
end start
这里显存的数据结构卡了我一下,导致我一开始老是输出微笑和奇怪的颜色,后来及时想起
果然ctrl+c大法在发功之前还是得仔细研究一下原理,复制不规范,代码两行泪 2.解决除法溢出的问题
assume cs:code
code segment
start:
mov ax,4240H;(ax)=L
mov dx,000FH;(dx)=H
mov cx,0AH;(cx)=N
call divdw
mov ax,4c00H
int 21H
divdw:
push ax;暂时存放一下
mov ax,dx
div cl;此时(al)=int(H/N),ah=rem(H/N)
mov bl,al
mov bh,0;构造int(H/N)*65536
mov di,bx;存放一下
mov bl,ah
pop ax;需要的时候再拿出来
mov bh,0;构造rem(H/N)*65536
mov dx,bx;构造rem(H/N)*65536+L
div cx;构造/N=(ax)
mov cx,dx;使(cx)=余数
add dx,di;构造int(H/N)*65536+/N
ret
code ends
end start
寄存器不够用是真的麻烦,也许这题还用不着堆栈,可以后更多参数和中间变量了怎么办 3.数值显示
assume cs:code
data segment
db 10 dup (0)
data ends
code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
call dtoc
mov dh,8
mov dl,3
mov cl,2
call show_str
mov ax,4c00H
int 21h
dtoc:
mov di,0
mov bx,10
mov cx,5
s0:
div bx;
add dl,30H
mov ,dl
mov dx,0
inc di
loop s0
ret
show_str:;借用实验9的代码
mov al,dh
mov bl,160
mul bl
add dl,dl;显存的奇数字节为字的内容,偶数为字的外观属性,所以要列地址*2作为显存地址
add al,dl
mov di,ax
mov bx,5
mov ax,0B800H;显存位置
mov es,ax
mov ah,cl
mov cx,5
s: dec bx
mov al,
mov es:,al
inc di
mov es:,ah
inc di
loop s
ret
code ends
end start
这里令我百思不得其解的是为何debug运行得很成功,但直接运行exe会卡住,希望有大大解答 流风逸雪 发表于 2020-4-11 18:55
3.数值显示
这里令我百思不得其解的是为何debug运行得很成功,但直接运行exe会卡住,希望有大大解答
首先,如果有问题,请写在问题贴中
你写在作业贴中很少有人看到你的问题,我看到这个问题纯属巧合
然后是你的问题
div bx
这条指令的含义是
dx:ax / bx
是32位 / 16位
请问执行这条指令之前dx的值是多少?
这就是C语言中的 “使用了未初始化的变量”
出现什么结果都是可能的,程序有时候正常,有时候异常,因为 “使用了未初始化的变量”
人造人 发表于 2020-4-11 21:46
首先,如果有问题,请写在问题贴中
你写在作业贴中很少有人看到你的问题,我看到这个问题纯属巧合
首先谢谢这位大大的回答。
我没写在问题贴的一个原因是我还没看完小甲鱼的关于这一段的课程,先暂时做个记录,看看能不能独立完成。放在作业贴是觉得会来看的应该是同样在做这一道题的童鞋,这样能得到同一层次的思考和反馈,不至于产生依赖。
我是看完小甲鱼视频再回来修改后才看到大大的回答的,我很认同大大的回答。
这里贴一下修改后的代码,修改后能直接运行exe了:assume cs:code
data segment
db 10 dup (0)
data ends
code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
mov si,0
call dtoc
mov dh,8
mov dl,3
mov cl,2
call show_str
mov ax,4c00H
int 21h
dtoc:
push dx
push cx
push ax
push si
push bx
mov bx,0;bx子程序中存放位数,用栈临时存放修改后的字符
s0:
mov cx,10d;d表示十进制
mov dx,0;这里小甲鱼的视频里确实做了dx的初始化,说明正如@人造人 所说,问题出在这
div cx;
mov cx,ax;所得商给cx
jcxz s2;当商为0跳到s2
add dx,30H;余数加上30h得到相应的ASCII码
push dx
inc bx;存储位数
jmp short s0
s2:
add dx,30H
push dx
inc bx;再进行一次栈操作(补充当“商为零而余数不为零“的情况)
mov cx,bx;总共有bx位进栈了,所以循环次数为bx
mov si,0
s3:
pop ax
mov ,al
inc si
loop s3
okay:
pop bx
pop si
pop ax
pop cx
pop dx
ret
show_str:;借用实验9的代码
push bx
push cx
push si
mov al,160
dec dh
mul dh
add dl,dl;显存的奇数字节为字的内容,偶数为字的外观属性,所以要列地址*2作为显存地址
add al,dl
mov bx,ax
mov ax,0B800H;显存位置
mov es,ax
mov di,0
mov al,cl
mov ch,0
s: mov cl,
jcxz ok
mov es:,cl
mov es:,al
inc si
add di,2
jmp short s
ok:
pop si
pop cx
pop bx
ret
code ends
end start
最后我想了一下,确实不应该在作业贴里问问题,毕竟鱼c作为一个开放的平台,应该把内容分类好方便更多的鱼油。{:5_105:} 对于第三题,为了让大家看的更清楚
更直观的明白毛病在哪,就把只修改第30行的代码放这以做对比:
这是原来的dtoc子程序:
dtoc:
mov di,0
mov bx,10
mov cx,5
s0:
div bx;
add dl,30H
mov ,dl
mov dx,0
inc di
loop s0
ret
这样无法直接运行exe
这是修改后的:
dtoc:
mov di,0
mov bx,10
mov cx,5
s0:
mov dx,0;其实就是单纯的把原来放在30行的mov dx,0放在这就行了
div bx;
add dl,30H
mov ,dl
;mov dx,0
inc di
loop s0
ret
这样可以直接运行exe了 流风逸雪 发表于 2020-4-12 14:45
首先谢谢这位大大的回答。
我没写在问题贴的一个原因是我还没看完小甲鱼的关于这一段的课程,先暂时做 ...
嗯,我同意你的观点,遇到问题应该先自己尝试解决,实在解决不了才提问,这样自己能得到更多知识
页:
[1]