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-

这里发生了什么?

4

5 回答 5

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
于 2008-09-18T13:52:13.450 回答
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 之前。

于 2008-09-18T13:58:06.887 回答
0

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

字符串后面的 0 char 中不需要。第 9 个函数不适用于以空字符结尾的字符串,这个 '$' 字符可以代替 0。

于 2008-10-06T13:25:59.853 回答
0

看起来你是 PSP 的一部分。这是一个.COM吗?如果您忘记了 ORG 100h 汇编器指令,则偏移量将不会指向您认为它们应该指向的位置……有趣的旁注是,仅从 MOV OFFSET 切换到 LEA 也将“起作用”。MASM 足够聪明,可以在您使用 LEA 时弄清楚您在做什么,而在使用 OFFSET 时可能不会(是的,我很久以前就很难学会这一切...... :-))。

于 2010-12-01T15:24:40.093 回答
-1

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

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

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

于 2008-09-18T13:53:51.450 回答