Error: Operation size not specified - NASm

23,389

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.)

Share:
23,389
Nathan
Author by

Nathan

Updated on July 11, 2020

Comments

  • Nathan
    Nathan almost 4 years

    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?

    Thanks :)

  • Nathan
    Nathan almost 8 years
    This looks perfect, thanks! About your last comment, I used memory because I'm not 100% sure what registers I'm safe to use for temp values like this. Which are best for this?
  • Peter Cordes
    Peter Cordes almost 8 years
    @Nathan: It depends on the ABI of the function. If you wrote both functions, you get to make up your own calling convention. Have a look at some existing ABIs / calling conventions in the x86 tag wiki. Microsoft's 32bit __vectorcall is probably a good starting point for 16bit code, where the first two integer args are passed in registers. (edx and ecx, IIRC). 32bit SysV (Linux) passes args on the stack exclusively. Even that would be a better choice than passing args in globals. (push works with a memory operand).
  • Ray Toal
    Ray Toal almost 8 years
    @Nathan: If you are using nasm in 64-bit mode, the integer valued parameters are passed in this order: rdi, rsi, rdx, rcx, r8, r9, so you would be likely to write your drawPixel function by packing your two coordinates into the low order 32 bits of rdi, namely edi. Within a function, should preserve rbp, rbx, r12, r13, r14, and r15. But there is much more to function calling conventions (including alignment, floating point registers, return values, etc.) so see nasm.us/doc/nasmdo11.html and x86-64.org/documentation/abi.pdf.
  • Chris K
    Chris K almost 8 years
    movs instruction?
  • Ray Toal
    Ray Toal almost 8 years
    movs would be great for moving large blocks of memory, but the OP was talking about moving 32 bits from one memory location to another, so I would avoid movs for sure. I did mention in my answer there was no simple memory-to-memory move instruction. I don't consider movs to be "simple" because of the implicit use of index registers. :-)