Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POP data from the stack into a named variable? Or store a register with MOV?

Tags:

assembly

nasm

I'm making a program where the user enters a number, it the program prints out from zero to that number. Here is my code:

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             ; }

The problem I am having is that it gives the error invalid combination of opcode and operand. I have tried declaring the variable other a word, double word, byte, and it still says that. Why does it?

In essence, my question is how can I move a value in a register to a value in memory? Such as:

mov memorydata, eax

Where memorydata is data declared in SECTION .data or something of the like.

like image 840
Progrmr Avatar asked Dec 18 '25 00:12

Progrmr


1 Answers

First, it should be pop [other] and not pop other. In NASM, other is just an address, while [other] represents the contents/data at that address. This is how NASM is different from TASM and MASM. pop other is asking NASM to generate an instruction popping data from the stack into a... constant! There's no such instruction and it would not make any sense to make one like that. You want to pop stuff into a register or memory.

Second, unlike TASM and MASM (again), NASM does not assign to label names any kind of type or size. Labels are just that, named locations (addresses) in code or data.

For that reason pop [other] is ambiguous to NASM because pop can pop a word or a double word and you don't specify which one you want and there's no way for NASM to guess the right size for you.

What you should write instead is either

pop word [other]

or

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

I strongly suggest not to push or pop 16-bit registers or variables or constants. They misalign the stack, which can lead to reduced performance and silly bugs due to attention loss (e.g. you push a 32-bit value and then mistakenly pop it as 16-bit or the other way around).

like image 102
Alexey Frunze Avatar answered Dec 20 '25 18:12

Alexey Frunze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!