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

问题描述

我正在解决一个基本问题,即汇编语言编程,以添加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],04
 MOV BL,05
 ADD AL,BL
 AAA
 MOV CX,CX
 MOV [0010],AX
 MOV AH,04CH
 INT 21H
CODE ENDS
END START

解决方法

您正在体验的是MASM语法中的一个怪癖。如果您的内存操作数中只有一个立即数而不是标签(即[0000][0010]),则MASM将生成一个Immediate mode Illegal错误。这样的指令确实没有任何问题,但是MASM具有特定的语法。您必须明确指定段寄存器。在这种情况下,许多汇编程序会假定 DS ,但MASM不会。

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

MOV [DS:0000],AX
MOV [DS:0010],AX

MASM还允许:

MOV DS:[0000],AX
MOV DS:[0010],AX

首选第一个,因为TASM(与MASM兼容的汇编器)不支持后一种形式。如果将段放置在其中,则该段应与MASM和TASM汇编器以及开源JWASM汇编器一起使用。

如果您的内存操作数包含一个寄存器和一个偏移量,则MASM不会报错,因此这是有效的MASM语法:

MOV [BX+0000],AX
MOV [BX+0010],AX

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

MOV WORD PTR [DS:0000],0100h
MOV BYTE PTR [DS:0000],00h

应注意,值0010是十进制10(不是十六进制)。目前尚不清楚是要在代码中使用十进制还是十六进制。十六进制值的后缀为H


注意:我对将现在已删除的段寄存器清零发表了评论。尽管我的评论是正确的,但我看起来还不够接近,无法意识到您已将DS设置为0000,因此您的代码正在访问0000:0000和0000:0010。在这方面,您的代码是正确的,尽管目前尚不清楚为什么要修改那部分内存。在IBM-PC兼容系统上,中断向量表(IVT)位于内存的前1024个字节中。您可能在与IBM-PC不兼容的系统上,而您所做的可能根本不是问题。我只是想提个醒。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...