Search code examples
assemblyx86dosmasmx86-16

Why does CX work in '[ ]' in 16 Bit Assembly when it is not a base or index register?


When using MASM 6.15 under DOSBox whenever I try to do:

mov al, [cx]

or

mov al, [cx + bx]

or

mov al, [cx + 4]

I am getting the error: 'Only Base or Index Registers are allowed'

But then again, let's say I have an array var1. If I do:

.model small
.stack 4096

.data
 var1 BYTE 1, 2, 3, 4, 5, 6, 7, 8, 9

.code
main proc
mov ax, @data
mov ds, ax

mov cx, 5
mov al, [var1 + cx]

mov ah, 4Ch
int 21h
main endp
end main

It works perfectly fine. Why doesn't it give the same error as above? CX is not a base or index register.

What is the whole working essence of the [] operator?


Solution

  • This is a bug in some versions of MASM. There are cases like these where MASM will try to incorrectly encode an instruction that shouldn't be possible. It should have thrown an error trying to encode this, as CX can't be used as a base or index in 16-bit addressing.

    mov al, [var1 + cx]
    

    Instead of generating an error it incorrectly generates it as:

    mov bh, var1[bx+si]
    

    The invalid instruction is encoded as:

    8A B8 xx xx
    

    Where xx xx is the offset of var1.