注册 登录
编程论坛 汇编论坛

[求助]为什么用INT 21H 的9号功能却输出了乱码

汪洋 发布于 2006-05-05 15:25, 2996 次点击

在下初学汇编,遇到一问题不明原因,请各位指教:
......
MESSAGE DB 'THIS IS A MESSAGE!$'
......
MOV DX,OFFSET MESSAGE
MOV AH,09H
INT 21H
......
可为什么输出结果却先是:一串乱码+"THIS IS A MESSAGE!"

13 回复
#2
lj_8606032006-05-05 15:32
DX没有清0吧,你在前面加上一句把DX清0,看看行不行.
#3
汪洋2006-05-05 15:37
谢谢,我这就试试
#4
汪洋2006-05-05 15:41

还是有乱码,
下面是我写的程序,可以帮我看看吗?
DATA SEGMENT
message DB 'this is a message!$'
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
mov dx,0
MOV DX,OFFSET message
mov ah,09h
INT 21H

MOV AH,4CH
INT 21H
CODE ENDS
END START

#5
公子吕2006-05-06 10:51

把message下面再定义一个变量,可以没有名字,象这样:
DATA SEGMENT
message DB 'this is a message!$'
db '$'
DATA ENDS

我的程序里也经常有这个问题,无法理解.
还有你最好在退出程序之前(MOV AH,4CH INT 21H)
加上 mov ah,7
int 21h ;等待按键
不然你的字符串显示闪了一下就没了,看得见吗?

#6
汪洋2006-05-06 11:00

谢谢公子的解答,我把昨天的程序加了两句就行了,MOV AX,DATA MOV DS,AX.但我不知道为什么应该加上这两句,不是ASSUME已经给DS分配了吗?
程序尾不加 MOV AH,7
INT 21H
在命令提示符下也能看到的,不会一下就没了。

DATA SEGMENT
MESSAGE DB 0ah,0dh,'this is a message!$'
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET MESSAGE
MOV AH,9
INT 21H

MOV AH,4CH
INT 21H
CODE ENDS
END START

#7
公子吕2006-05-06 13:46
我晕.你原来的那个程序我还真没仔细看,
MOV AX,DATA ;DATA是数据段起始地址
MOV DS,AX ;数据段地址通过AX送到数据段寄存器DS中.

这两句是必须有的.因为后面的09中断就是在DS:DX处取字符串.
#8
汪洋2006-05-06 16:10
ASSUME CS:CODE,DS:DATA的作用不是把DATA的段地址赋给DS吗?
为什么这里还要再赋一次呢?
#9
公子吕2006-05-06 17:49

ASSUME只是告诉汇编程序建立段与段寄存器之间的联系,规定对某个段寻址时用哪个段寄存器提供段地址
但是并不设置段寄存器的初值. 假如你这样:
ASSUME DS:CODE,CS:DATA
那么程序访问DATA里的数据,它就会用CS寻址,而不是DS了.

#10
汪洋2006-05-06 20:43

如果不写把DATA的段地址赋给DS,也就是说如果不写
MOV AX,DATA
MOV DS,AX
的话,编译器会从什么地方找DATA段和CODE段?
我刚开始出现乱码的程序输出中有乱码,但最后还是包含了正确的那个字符串。
这是不是说明如果不这样写,编译器也能“估计”出该在什么地方找相应的段?
问题太多了,哈哈,各位大侠,能继续指教吗?

#11
lj_8606032006-05-06 22:06
有问题就问.
ASSUME这句只是声明,并没有干其他事.你如果缺了MOV AX,DATA和MOV DS,AX这两句就不行,因为这两句把数据的地址存储到寄存器中,假如没有这两句,那么,编译器无法识别寄存器中你写的代码的前面的内容(这句好好理解),所以出现乱码.
#12
汪洋2006-05-07 09:53

我相信你们已经把这个问题表达得很清楚了,
但我还是不能完全理解,
也许这本来就是一个需要时间才能解决的问题。

#13
公子吕2006-05-07 11:22
以下是引用汪洋在2006-5-6 20:43:00的发言:

如果不写把DATA的段地址赋给DS,也就是说如果不写
MOV AX,DATA
MOV DS,AX
的话,编译器会从什么地方找DATA段和CODE段?
我刚开始出现乱码的程序输出中有乱码,但最后还是包含了正确的那个字符串。
这是不是说明如果不这样写,编译器也能“估计”出该在什么地方找相应的段?
问题太多了,哈哈,各位大侠,能继续指教吗?

有了这个:ASSUME CS:CODE,DS:DATA你的汇编器就知道访问DATA的时候用DS寻址.访问代码的时候用CS寻址.但由于没有给DS赋初值,所以DS的值是未知的.显示字符串的时候虽然有乱码,而你的字符串也被输出了,说明DS的值和正常的初值相差不是很大,猜想是程序装载和重定位的时候系统作的工作.

#14
汪洋2006-05-07 14:27

哈哈,我现在终于明白了,谢谢!

1