错误:未指定操作大小 - NASm

Nat*_*han 6 assembly nasm mov x86-16

我正在使用 16 位 NASM 程序集,但存在无法构建代码的问题。错误发生在此处的所有 MOV 行上:

  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
Run Code Online (Sandbox Code Playgroud)

我读到这是因为汇编程序不知道变量的大小。我尝试MOV [pixel_x], byte [x_coord]过一些在线帖子的建议,但这给出了同样的错误。我只想将x_coord和y_coord的前两个字节复制到pixel_x/pixel_y中,然后是接下来的两个,然后是接下来的两个,然后是接下来的两个。我怎样才能使这项工作?

谢谢 :)

Ray*_*oal 10

处理器没有简单的内存到内存移动指令,所以如果你想一次移动两个字节,正确的做法是使用寄存器作为中介:

MOV ax, word [x_coord]
MOV word [pixel_x], ax
MOV ax, word [y_coord]
MOV word [pixel_y], ax
CALL DrawPixel
Run Code Online (Sandbox Code Playgroud)

由于您的变量在内存中是连续的,您也可以这样做:

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
Run Code Online (Sandbox Code Playgroud)

如果您只绘制四个像素,则可以一个接一个地进行调用:

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
Run Code Online (Sandbox Code Playgroud)

如果你有更多的像素画,你可以考虑写一个循环。

(另外:还考虑实现DrawPixel使用寄存器中的值。)

  • @Nathan:这取决于函数的 ABI。如果您编写了这两个函数,您就可以制定自己的调用约定。在 [x86 tag wiki](http://stackoverflow.com/tags/x86/info) 中查看一些现有的 ABI/调用约定。Microsoft 的 32 位 __vectorcall 可能是 16 位代码的良好起点,其中前两个整数参数在寄存器中传递。(edx 和 ecx,IIRC)。32 位 SysV (Linux) 仅在堆栈上传递参数。即使这样也比在全局变量中传递 args 更好。(`push` 与内存操作数一起使用)。 (2认同)