Sham
Sham

Reputation: 71

Difference between "mov eax, [num]" and "mov eax, num"

I am a beginner and writing assembly program to print numbers from 1 to 9 using this code:

section .text    
   global _start                    
_start:                     
   mov ecx,10    
   mov eax, '1'     
l1:    
   mov [num], eax    
   mov eax, 4    
   mov ebx, 1    
   push ecx     
   mov ecx, num            
   mov edx, 1            
   int 0x80     
   mov eax, [num]    
   sub eax, '0'    
   inc eax    
   add eax, '0'    
   pop ecx    
   loop l1      
   mov eax,1             ;system call number (sys_exit)    
   int 0x80              ;call kernel    
section .bss    
num resb 1

Here we have following three statements:

  1. mov [num], eax
  2. mov ecx , num
  3. mov eax, [num]

I want to know why we should use mov ecx,num rather than mov ecx,[num]

Upvotes: 4

Views: 20031

Answers (2)

Mike Nakis
Mike Nakis

Reputation: 61986

WhatsUp's answer is not wrong, but I will try to give a different answer, hopefully a better one.

The directive num resb 1 reserves one byte of memory and declares a label to refer to it. In this case, the label is "num". Unfortunately, this might tempt you think that num stands for the value of that byte, but that is wrong! Instead, num stands for the address of that byte.

As you know, addresses are also just numbers. One of the main reasons why we use assemblers is so that we do not have know, or deal with, addresses by number. The resb directive allows us to just assign the symbol num to stand for the address of that byte, and let the assembler worry exactly which address this is.

Let us assume that behind the scenes, the assembler picks address 0x01000100 to be what num stands for. This means that the assembler directive num resb 1 is equivalent to saying in a high-level language const int num = 0x01000100;

As you might also know, memory is like an array of bytes. So, in pseudocode, memory can be thought of as this:

byte[] memory = new byte[1073741824]; //1 gigabyte of memory

Therefore:

The following would assign 0x01000100 to ecx:

ecx = num; 

The following would assign the contents of memory location 0x01000100 to ecx:

ecx = memory[num];

(Ignoring for a moment that ecx is not one, but four bytes long.)

To summarize, whenever you see something in square brackets, e.g. [X] think of it as memory[X]. In other words, think of it as using X as an index into the memory array, which stands for the entire memory of your computer. When you think of it like this, the square brackets notation makes sense, doesn't it?

Upvotes: 1

WhatsUp
WhatsUp

Reputation: 1626

If you are familiar with C/C++, here is an explanation.

mov ecx, num is equivalent to:

int num;
ecx = & num;

while mov ecx, [num] is equivalent to :

int num;
ecx = num;

Here, the reason for the line mov ecx, num is because you are calling the system function int 0x80, which requires that ecx contains the address of your numbers. So it should be like that.

Upvotes: 10

Related Questions