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

时间:2012-10-12 07:07:11

标签: 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             ; }

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

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

mov memorydata, eax

其中memorydata是在SECTION .data或类似内容中声明的数据。

2 个答案:

答案 0 :(得分: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]

pop some_32_bit_register ; e.g. pop eax
mov [other], that_same_32_bit_register_s_lower_half ; e.g. mov [other], ax

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

答案 1 :(得分:0)

你需要弹出一个临时寄存器,然后移动到你的记忆目的地:

POP EAX
MOV myVar,EAX

或者,您需要弹出一些明确的语法:

POP WORD PTR[<word_sized_var>]

至于将内容移入内存中,有一些语法方法:

MOV <var name>,<value>

MOV [<var name>],<value>

在您的情况下,您可能想要第一个:MOV other,EBP