assemblynasmx86-16osdevreal-mode

NASM: Invalid effective address in Real Mode


I am trying to draw to screen in Real Mode, so I am trying to access 0xB8000 using segmentation

My assembly code is this

[BITS 16]
org 0x7c00

begin:
  mov ah, 0x01 ; disable cursor
  mov ch, 0x3f
  int 0x10

  mov ch, 0x0000
  mov cs, 0xb800
  mov ah, 0x0000
  mov [cs:ah], ch ; invalid effective address

end:
  jmp end

times 510 - ($-$$) db 0
dw 0xaa55

How would I address 0xB8000 using segmentation properly?


Solution

  • Remember that cs is the code segment register. You can't mov into it. And even if you could you wouldn't like the results; since cs:ip is used to determine where to fetch instructions, you would find your CPU executing the contents of video memory. So you should use either ds or es instead.

    Next, you can't load a segment register with an immediate; you can only load it from another register or from memory.

    Finally, you can't use an 8-bit register like ah as the offset part of an address: offsets are 16 bits. In fact, the only registers that can be used in an effective address for 16-bit 8086 are bx, si, di, bp. See differences between general purpose registers in 8086. (bp addressing uses the ss segment instead of ds unless overwritten, so probably shouldn't be your first choice here.)

    So a few options you could use instead:

    mov ax, 0xb800
    mov ds, ax
    mov bx, 0x0000 ; but xor bx, bx is more efficient
    mov [bx], ch
    
    mov ax, 0xb800
    mov es, ax
    mov bx, 0x0000
    mov [es:bx], ch
    
    mov ax, 0xb800
    mov es, ax
    mov [es:0x0000], ch
    

    As a general principle, when writing in assembly, you can't just guess as to which instructions take which combinations of operands; you have to look it up. You can only use those forms which the architecture actually implements, and sometimes their choices don't follow what you might logically assume. There are patterns which you may begin to recognize over time, but as a beginner, plan on referring to the instruction reference for every line you write.