2008-09-18 62 views
0

我有一些代码应该显示一条短消息。下面是相关代码:什么会导致汇编语言程序显示“垃圾”?

DATA SEGMENT 'DATA' 
MSG DB 0AH, 0DH, 'Hello, Adam', '$' 
CHAR DB 00H 
DATA ENDS 

CODE SEGMENT 'CODE' 
PRINT_MSG: 
    MOV AH, 09H ;Command to print string of characters 
    MOV DX, OFFSET MSG ;Mov address of message into DX 
    INT 21H  ;DOS Interrupt 
    JMP WAITING ;Loop back to waiting state 
CODE ENDS 

,输出是:

E:\ece323\software\lab2>MAIN.EXE 
?F ^?¶ ? N? ?    -!- 

Hello, Adam- 

这到底是怎么回事?

+3

我不禁注意到你没有接受,投票或评论任何答案;他们都没有帮你做作业吗? – 2008-09-19 17:21:40

回答

2

我的猜测是你的DS没有指向你的数据段。

Int21函数0x09取DS:DX中的字符串。

请记住,DX只是一个16位寄存器。要访问16位范围以外的数据,您必须使用段寄存器。这些被称为数据的DS和ES,代码的CS和堆栈的SS(在i386上也有FS和GS)。

加载的确切地址由16 * segment_register + offset_register给出。 Int21无法猜测DS的位置,因此必须在调用中断之前加载它。

我想你从来没有初始化你的DS寄存器,所以它很可能指向代码而不是数据段。

尝试更换您的

MOV DX, offset MSG 

由:

LDS DX, MSG ; Check that, it's been ages since I've written 16 bit code. 

Unfortunatley它已经多年,因为我已经最后的16位汇编发挥,所以我不能签,但应该LDS做的伎俩。

您也可以间接地在你的程序启动这样的加载DS的东西:

MOV AX, SEG DATA ; check that - can be SEGMENT or so as well. 
    MOV DS, AX 
-1

我的猜测是,你可能不会在“真实”的模式,这是需要在一般的MSDOS程序运行(和特定的21h中断)工作。

自Windows 95以来,Windows一直以“受保护”模式运行;命令提示符一直处于保护模式,因为我认为,Windows 2000.

您可能想尝试创建快捷方式EXE,然后在快捷方式中设置兼容性选项。

+1

Windows命令提示符将模拟所有这些东西给你,并让你调用int21就好了。所有DOS程序(.EXE和.COM)都以16位模式启动。 无需设置兼容性选项。 – 2008-09-18 13:56:28

0

尝试下面的变化:

DATA SEGMENT 'DATA' 
ERROR_MSG DB 'DS:DX is wrong' 
MSG DB 0AH, 0DH, 'Hello, Adam', '$' 
CHAR DB  00H 
DATA ENDS 

如果错误消息显示然后DS:DX是错误的,所以无论是DS不指向数据段,或“OFFSET MSG”是错误的一些原因...我的asm很生锈,但是尝试使用ADDR代替OFFSET(?)

如果错误消息没有显示,问题在执行到达PRINT_MSG之前发生。

0

Nils是对的,需要设置DS寄存器才能使用int 21的这个函数。先尝试第二部分与EAX转换,它应该可以工作。

并且在字符串之后没有必要在0个字符中。第9个函数不能使用以空字符结束的字符串,这个'$'字符的作品而不是0.

0

看起来像你显示的是PSP的一部分。这是一个.COM任何机会?如果您忘记ORG 100h汇编程序指令,则OFFSET不会指向您认为它们应该在的位置......作为一个有趣的方面说明,从MOV OFFSET切换到LEA也将“工作”。 MASM很聪明,能够弄清楚你在使用LEA时所做的事情,而不是使用OFFSET(是的,我很久以前就学会了这种困难的方法...... :-))。