Assembly 什么会导致汇编语言程序显示;垃圾;?

Assembly 什么会导致汇编语言程序显示;垃圾;?,assembly,x86,masm,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 in

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

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-

这是怎么回事?

我猜您的DS没有指向您的数据段

Int21函数0x09从DS:DX获取字符串

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

从中加载的确切地址由16*段寄存器+偏移寄存器给出。Int21无法猜测DS的位置,因此必须在调用中断之前加载它

我猜您从未初始化过DS寄存器,因此它很可能指向代码,而不是数据段

试着换掉你的衣服

  MOV DX, offset MSG
作者:

不幸的是,我上一次使用16位汇编程序已经有好几年了,所以我不能检查它,但LDS应该会做这件事

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

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

我的猜测是,您可能没有在“真实”模式下运行,这通常是MSDOS程序(以及特定的Int 21h中断)工作所必需的

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


您可能希望尝试创建一个快捷方式do You EXE,然后在快捷方式中设置兼容性选项。

尝试以下更改:

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之前。

Nils正确,需要设置DS寄存器才能使用int 21的此功能。首先尝试EAX转换的第二部分,它肯定会工作


字符串后面不需要0个字符。第9个函数不适用于以null结尾的字符串,此“$”字符可以代替0。

看起来您是PSP的显示部分。这是a.COM吗?如果您忘记了ORG100H汇编程序指令,偏移量将不会指向您认为应该的位置。。。有趣的是,从MOV偏移量切换到LEA也会“起作用”。MASM足够聪明,可以在您使用LEA时了解您在做什么,而它可能不使用OFFSET(是的,我很久以前就知道了这一切…:-)。

Windows命令提示符将为您模拟所有这些内容,并允许您调用int21。此外,所有DOS程序(.EXE和.COM)都以16位模式启动。不需要设置兼容性选项。
DATA    SEGMENT 'DATA'
ERROR_MSG DB 'DS:DX is wrong'
MSG DB  0AH, 0DH, 'Hello, Adam', '$'
CHAR    DB      00H
DATA ENDS