将数据从寄存器移动到NASM中的内存中

Pro*_*rmr 2 assembly nasm

我正在创建一个用户输入数字的程序,程序从零打印到该数字.这是我的代码:

SECTION .DATA
len  EQU 32

SECTION .bss
data resw len
other resw len 
SECTION .TEXT

GLOBAL _start
_start:

input:                  ; This section gets the integer from the user
mov eax, 3          ; }
mov ebx, 1          ; }
mov ecx, data       ; } System_read call
mov edx, len        ; }
int 80h             ; }

prelim:
mov ebp, 0

setup:                  ; This section sets up the registers ready for looping 
push ebp
pop other        ; THIS IS THE ERROR LINE!
mov esi, data 

loop:                   ; This section loops, printing out from zero to the number given
mov eax, 4
mov ebx, 1
mov ecx, other 
mov edx, len
int 80h
cmp ebp, esi
je exit
inc ebp
jmp setup
exit:                   ; Exits the program
mov eax, 1          ; }
mov ebx, 0          ; } System_exit call
int 80h             ; }
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是它给出了错误invalid combination of opcode and operand.我已经尝试将变量声明other为单词,双字,字节,它仍然说明了.为什么呢?

从本质上讲,我的问题是如何将寄存器中的值移动到内存中的值?如:

mov memorydata, eax
Run Code Online (Sandbox Code Playgroud)

memorydata声明的数据在哪里SECTION .data或类似的东西.

Ale*_*nze 8

首先,它应该是pop [other]而不是pop other.在NASM中,other只是一个地址,而[other]代表该地址的内容/数据.这就是NASM与TASM和MASM的不同之处.pop other要求NASM生成一个从堆栈弹出数据到......常量的指令!没有这样的指示,制作这样的指令是没有任何意义的.你想把东西放进寄存器或内存中.

其次,与TASM和MASM(再次)不同,NASM不会将标签名称分配给任何类型或大小.标签就是代码或数据中的命名位置(地址).

因为这个原因pop [other]对于NASM是不明确的,因为pop可以弹出一个单词或一个双字,而你没有指定你想要的那个,并且NASM无法为你猜出合适的大小.

你要写的也是

pop word [other]
Run Code Online (Sandbox Code Playgroud)

要么

pop some_32_bit_register ; e.g. pop eax
mov [other], that_same_32_bit_register_s_lower_half ; e.g. mov [other], ax
Run Code Online (Sandbox Code Playgroud)

我强烈建议不要推送或弹出16位寄存器或变量或常量.它们使堆栈不对齐,这可能导致性能下降和由于注意力丢失导致的愚蠢错误(例如,您推送32位值然后错误地将其弹出为16位或反之).