我正在创建一个用户输入数字的程序,程序从零打印到该数字.这是我的代码:
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或类似的东西.
首先,它应该是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位或反之).