MASM: How to resolve Immediate mode Illegal in 8086 programming?

3.1k views Asked by At

I am solving a fundamental question of Assembly Language Programming to add BCD numbers and two ASCII numbers, for that I got that I have to use DAA and AAA instructions respectively, Now I am trying to store the result stored in AX register into my desirable memory location, but not getting that why the following code is giving me error Immediate mode Illegal Below is the code that I have coded till now, please help me that how to eradicate this error PS: I want to move my result into my required memory location only not any special purpose register

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
1

There are 1 answers

1
Michael Petch On BEST ANSWER

What you are experiencing is a quirk in MASM syntax. When you have a memory operand with just an immediate value in it that isn't a label (ie [0000] or [0010]), MASM will generate an Immediate mode Illegal error. There really isn't anything wrong with such an instruction, but MASM has specific syntax for it. You must explicitly specify the segment register. Many assemblers will assume DS for this case but MASM doesn't.

To get around this problem use this syntax:

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

MASM also allows:

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

The first one is preferred since TASM (A MASM compatible assembler) doesn't support the latter form. If you place the segment inside it should work with both MASM and TASM assemblers as well as the open source JWASM assembler as well.

If your memory operand includes a register and an offset then MASM will not complain, so this is valid MASM syntax:

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

If you wish to move an immediate value (source) to a memory address that is just an immediate reference then the syntax looks like:

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

It should be noted that the value 0010 is decimal 10 (not HEX). It is unclear if you meant to use decimal or hex in your code. HEX values have an H suffix.


Note: I made a comment about zeroing a segment register that is now deleted. Although my comment was correct I didn't look close enough to realize that you did set DS to 0000 so your code is accessing 0000:0000 and 0000:0010. In that regard your code is correct although it is unclear why you are modifying that part of memory. On an IBM-PC compatible system the interrupt vector table (IVT) is in the first 1024 bytes of memory. You may be on a non IBM-PC compatible system and what you are doing may not be a problem at all. I just wanted to give you a heads-up about it.