MASM:如何解决 8086 编程中的立即模式非法?

Ank*_*kur 2 assembly dos masm addressing-mode x86-16

我正在解决汇编语言编程的一个基本问题,以添加 BCD 数字和两个 ASCII 数字, 为此我必须分别使用DAA 和 AAA指令,现在我正在尝试将存储在 AX 寄存器中的结果存储到我想要的内存中位置,但不明白为什么下面的代码给我错误立即模式非法 下面是我到目前为止编码的代码,请帮助我如何消除这个错误 PS:我想将我的结果移动到我需要的内存位置只是没有任何特殊用途的寄存器

ASSUME CS:CODE,DS:DATA
DATA SEGMENT
DATA ENDS
CODE SEGMENT
START:
 MOV AX,0000H
 MOV DS,AX
 MOV AL,59
 MOV BL,35
 ADD AL,BL
 DAA
 MOV CX,0000
 MOV ES,CX
 MOV [0000],AX
 MOV AL,04
 MOV BL,05
 ADD AL,BL
 AAA
 MOV CX,0000
 MOV ES,CX
 MOV [0010],AX
 MOV AH,04CH
 INT 21H
CODE ENDS
END START
Run Code Online (Sandbox Code Playgroud)

Mic*_*tch 6

您遇到的是 MASM 语法中的一个怪癖。当您的内存操作数中只有一个非标签(即[0000][0010])的立即数时,MASM 将生成Immediate mode Illegal错误。这样的指令确实没有任何问题,但 MASM 有特定的语法。您必须明确指定段寄存器。在这种情况下,许多组装者会假设DS,但 MASM 不会。

要解决此问题,请使用以下语法:

MOV [DS:0000],AX
MOV [DS:0010],AX
Run Code Online (Sandbox Code Playgroud)

MASM 还允许:

MOV DS:[0000],AX
MOV DS:[0010],AX
Run Code Online (Sandbox Code Playgroud)

第一个是首选,因为 TASM(MASM 兼容的汇编程序)不支持后一种形式。如果将段放在里面,它应该适用于 MASM 和 TASM 汇编器以及开源 JWASM 汇编器。

如果你的内存操作数包含一个寄存器和一个偏移量,那么 MASM 不会抱怨,所以这是有效的 MASM 语法:

MOV [BX+0000],AX
MOV [BX+0010],AX
Run Code Online (Sandbox Code Playgroud)

如果您希望将一个立即值(源)移动到一个只是一个立即引用的内存地址,则语法如下所示:

MOV WORD PTR [DS:0000], 0100h
MOV BYTE PTR [DS:0000], 00h
Run Code Online (Sandbox Code Playgroud)

需要注意的是,0010 的值是十进制的 10(不是十六进制)。目前尚不清楚您打算在代码中使用十进制还是十六进制。HEX 值有一个H后缀。


注意:我发表了关于将现在删除的段寄存器归零的评论。尽管我的评论是正确的,但我看起来还不够仔细,以至于没有意识到您确实将 DS 设置为 0000,因此您的代码正在访问 0000:0000 和 0000:0010。在这方面,您的代码是正确的,尽管尚不清楚您为什么要修改那部分内存。在 IBM-PC 兼容系统上,中断向量表 (IVT) 位于内存的前 1024 字节中。您可能使用的是与 IBM-PC 不兼容的系统,并且您正在执行的操作可能根本没有问题。我只是想给你提个醒。

  • Ross 对 [MASM32 中的混淆括号](/sf/ask/1759082041/) 的回答显示了当其中没有寄存器时 MASM 基本上如何忽略 `[]` 的示例。 (3认同)