assemblynasmx86-16mov

Error: Operation size not specified - NASM


I'm working in 16 bit NASM assembly having an issue where my code won't build. The error happens on all the MOV lines here:

  section .bss
  x_coord   RESB 8 ; [x_coord] is the head, [x_coord+2] is the next cell, etc.
  y_coord   RESB 8 ; Same here
  pixel_x  RESB 2  ; Storage for calculations
  pixel_y  RESB 2  ; Storage for calculations

   ...


  MOV [pixel_x], [x_coord]
  MOV [pixel_y], [y_coord]
  CALL DrawPixel

  MOV [pixel_x], [x_coord+2]
  MOV [pixel_y], [y_coord+2]
  CALL DrawPixel

  MOV [pixel_x], [x_coord+4]
  MOV [pixel_y], [y_coord+4]
  CALL DrawPixel

  MOV [pixel_x], [x_coord+6]
  MOV [pixel_y], [y_coord+6]
  CALL DrawPixel

I've read that this happens because the assembler doesn't know what size the variables are. I tried MOV [pixel_x], byte [x_coord] suggested by some online post but that gives the same error. I just want to copy the first two bytes of x_coord and y_coord into pixel_x/pixel_y, then the next two, then the next two, then the next two. How can I make this work?


Solution

  • The processor does not have a simple memory-to-memory move instruction, so the right thing to do, if you want to move two bytes at a time, is to use a register as an intermediary:

    MOV ax, word [x_coord]
    MOV word [pixel_x], ax
    MOV ax, word [y_coord]
    MOV word [pixel_y], ax
    CALL DrawPixel
    

    Since your variables are contiguous in memory, you might also be able to do this:

    MOV eax, dword [x_coord]  ; move BOTH x_coord AND y_coord into the register
    MOV dword [pixel_x], eax  ; populates BOTH pixel_x AND pixel_y
    CALL DrawPixel
    

    If you are only drawing four pixels, you can do the calls one after the other:

    MOV eax, dword [x_coord]
    MOV dword [pixel_x], eax
    CALL DrawPixel
    MOV eax, dword [x_coord+2]
    MOV dword [pixel_x], eax
    CALL DrawPixel
    MOV eax, dword [x_coord+4]
    MOV dword [pixel_x], eax
    CALL DrawPixel
    MOV eax, dword [x_coord+6]
    MOV dword [pixel_x], eax
    CALL DrawPixel
    

    If you had more pixels do draw, you might consider writing a loop.

    (Aside: also consider implementing DrawPixel to use values from a register.)