0

So I am trying to learn assembly(NASM). The issue is that the resources for assembly are very basic-theoretical and rare, and I cannot understand very basic things. I know that assembly registers are used as "variables" on the processor's "memory". But the issue is that for example in this "hello world" type program:

section .text
   global _start     ;must be declared for linker (gcc)
    
_start:          ;tell linker entry point
   mov  edx,len  ;message length
   mov  ecx,msg  ;message to write
   mov  ebx,1    ;file descriptor (stdout)
   mov  eax,4    ;system call number (sys_write)
   int  0x80     ;call kernel
    
   mov  eax,1    ;system call number (sys_exit)
   int  0x80     ;call kernel
    
section .data
msg db 'Hello from assembly!',0xa ;a message
len equ $ - msg  ;length of message

I cannot understand WHY we save for example the message length on edx and the message to write on ecx, when for example here in tutorialspoint it says:

Description Of Registers

So here I assume that since ECX should have the loop counter, in a C-like program:

for(int i = 0; i < 5; i++) 
{
      printf("Hey!\n");
}

the ECX register should contain the i. But on the program above, we save the message on ECX.

Similarly, I am confused about where we save the arguments when we want to call C functions from assembly, but I assume that since this is more advanced, if I understand what I save in which registers, gradually I would understand what happens in case i want to call C functions.

Thank you!

Community
  • 1
  • 1
  • The documentation for int 0x80 tells you what registers you need to use. – Hans Passant Mar 27 '18 at 10:16
  • 1
    imagine there's lot of code behind the `int 0x80` functionality, it's not a magic that the message is printed. And this code is already compiled in certain way, to expect string memory address in `ecx`, so you have to adjust your code to have expected arguments in expected registers before calling system service. The service code has no chance to guess into which register you did put which argument, it must be fixed, as you can't "tag" register with what kind of value it does hold. If you put into `ecx` memory address, or integer, or float, it's just 32 bits, no difference or some "type". – Ped7g Mar 27 '18 at 10:56
  • 2
    And the registers are sort of sparse resource, so you should often think twice about your algorithm, to design code which is using reasonable amount of registers, for example it is not uncommon to readjust your algorithm to use the same value as counter and array indexing (counting for example from -5 to 0), etc.. If you have `ecx` free, using it as counter makes sense, but in your example, if you would want to print the message 5 times, it would make more sense to use some free register for counter, like `ebp/esi/edi`. – Ped7g Mar 27 '18 at 11:04
  • You guys are marvellous! I up-voted you all, and i wish i could accept more than one answer. I chose to accept the one from @kristjank because it was first one that answered and because of its simplicity. –  Mar 27 '18 at 12:40
  • 1
    In your example, the only use of registers is for arg-passing to system calls. The program has no variables. (Well, you could call `msg` an array variable. You did put it in the read/write data section, so the equivalent in C would be `char msg[] = { 'H', 'e', ..., '\n' };`, not `const char msg[]...` (And not a string literal initializer because the array doesn't end with a `0` byte; it's not a C implicit-length string.) – Peter Cordes Mar 28 '18 at 03:02

3 Answers3

1

Registers are independent data storage devices so it doesn't really matter in which you store your data unless a function or an instruction requires you to do so.

In this case, it's required by the Linux system call that the data is stored in a specific register. In other cases, these rules are to be treated more like good practices: you should follow them, but you don't necessarily have to if nothing requires it.

  • To say it another way, there are some instructions that can only use certain registers, but the existence of those instructions doesn't mean anything if you don't use them (in that specific block of code). – Peter Cordes Mar 27 '18 at 22:52
1

The descriptions are kind of a backronym - trying to explain the register naming retroactively. It might help you to remember the additional special uses of the registers, which are otherwise general purpose. However, it is not really the reason for the register names.

The Intel processor series started with the 4004 having a single accumulator, simply called register A.

When later models added more registers, the next one after A could perhaps be called A2 or maybe B. So it happened to become B. After that it is only "natural" to use C and D for another pair of registers. Now we are on the 8-bit CPUs.

When designing the 8086 as a 16-bit device, the old 8-bit registers A, B, C, and D were made 16-bit and named AX, BX, CX, and DX. And, at the same time, they were made more general purpose than in the 8080.

As they are general purpose registers, they can be used for other things than what their backronym names suggest. For example, CX (or ECX) can very well store a pointer to a string instead of holding a loop count.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
0

I once struggled with it all and people didn't help. I was just called a troll (srsly?).

What is a register?

A register is a simple data storage the processor has that is very small (usually 16, 32 or 64 bit) but very fast.

They can be used to store data or addresses to memory.

What's the point of all different registers?

1) You can't use one register to hold all your data (unless you're good with confusing binary stuff).

2) Instructions use different registers (for example, the LOOP instruction uses the count register, which is CX).

What about memory or a hard drive?

Registers are usually required for things like maths (eat your vegetables too!). Memory is slower than registers and you have to manage it.

This example might be confusing for you but it's like gold and money. Gold does not have an economy but it is valuable and rare. You can easily get money, but it is more confusing on how it works.

Hard drives should not be used for anything with Assembly, unless you need to access a file.

Steve Woods
  • 227
  • 1
  • 9
  • To actually answer the question, make one further point: If you *aren't* using [the slow `loop` instruction](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently) in that particular block of code, then ECX is just another register you can use for anything else. i.e. there are some instructions that can only use certain registers, but the existence of those instructions doesn't mean anything if you don't use them. – Peter Cordes Mar 27 '18 at 22:51