什么可以导致汇编语言程序显示“垃圾”?

时间:2008-09-18 13:40:14

标签: assembly x86 masm

我有一些应该显示短消息的代码。这是相关的代码:

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-

这里发生了什么?

5 个答案:

答案 0 :(得分: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.

不幸的是,自从我上次使用16位汇编程序以来已经好几年了,所以我无法检查它,但是LDS应该可以解决这个问题。

您也可以通过以下方式在程序启动时间接加载DS:

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

答案 1 :(得分: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不指向DATA段,或者'OFFSET MSG'由于某种原因出错...我的asm生锈但是尝试ADDR而不是OFFSET(?)

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

答案 2 :(得分:0)

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

字符串后面的0字符串不需要。第9个函数不适用于空终止字符串,这个'$'char工作而不是0。

答案 3 :(得分:0)

看起来你正在展示PSP的一部分。这是一个.COM吗?如果您忘记了ORG 100h汇编程序指令,OFFSETs将不会指向您认为应该指向的位置......有趣的是,只需从MOV OFFSET切换到LEA也将“正常工作”。 MASM非常聪明,能够弄清楚当你使用LEA时你正在做什么,而它可能不会使用OFFSET(是的,我很久以前就用这种方式学到了所有这些...... :-))。

答案 4 :(得分:-1)

我的猜测是你可能没有以“Real”模式运行,这对于MSDOS程序(特定是Int 21h中断)来说是必需的。

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

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