I know a bit about Assembly. So let me first introduce the codes, then explain my way of thinking.
#This is the Assembly version.
pushq %rbp
movq %rsp, %rbp
movl $2, -4(%rbp)
movl $3, -8(%rbp)
movl $5, %eax
popq %rbp
ret
#This is the C version.
int twothree() {
int a = 2;
int b = 3;
return 2 + 3;
}
Alright, so the first thing that stares me is that we do not use the variables a and b as a + b. So they are unnecessary, we directly sum the integers. Yet, if computers were able to understand that, I guess it would be really scary. So, my question is that: How did this assembly code work without any addl or similar command? We directly move the Immediate (or constant) integer 5 to eax registrar.
Also, quick question. So what happens to the a and b variables after last two lines? Their position in stack (or maybe we can call the 'registrars' they used as a memory place) are free now as we use malloc + free. Is it true or at least logical? popq %rbp is the command for closing the stack I guess.
I am not an expert in Assembly as I said. So most of these thoughts are just thinking. Thanks!
The compiler saw that you were adding two numbers 2 + 3. And the compiler calculated that 2+3=5 and it put 5 in the assembly code. This is called "constant folding".
I guess you have optimization turned off in your compiler since it didn't delete the useless variables a and b. But constant folding is very easy for the compiler (unlike other kinds of optimization) and useful, so it seems that the compiler is doing it even when you don't turn on optimization.
As you figured out, the assembly code does not add 2 and 3 because there is no addl or similar command. It just does return 5;
There are no commands or codes in assembly programming. Instead, assembly code (uncountable) comprises instructions and directives.
Where do you see a use of malloc or free? These are functions for managing dynamic memory which isn't something your program uses. If either of these function were used, you'd have a call malloc or call free instruction in the code somewhere. The variables a and b are all in automatic storage, i.e. on the stack.
Now what happens in your code is that the compiler has performed constant folding to emit code as if you wrote
#This is the C version.
int twothree() {
int a = 2;
int b = 3;
return 5;
}
This is something the compiler does regardless of optimisation flags. So indeed, no addition is happening at run time. It was already performed during constant folding at compile time.
Also, quick question. So what happens to the a and b variables after last two lines? Their position in stack (or maybe we can call the 'registrars' they used as a memory place) are free now as we use malloc + free. Is it true or at least logical? popq %rbp is the command for closing the stack I guess.
The variables were stored in the red zone, a 128 byte region of memory below the stack pointer which is free for use as a scratch without having to explicitly allocate it. Thus, no code is needed to allocate or release storage for them.
Now, there is no such thing as “closing the stack.” The stack is a region in memory. The top of the stack is pointed to by the stack pointer rsp whereas the base pointer rbp points to the bottom of the current stack frame. You'll often see code like
push %rbp
mov %rsp, %rbp
...
pop %rbp
to establish and tear down a stack frame for the function at its beginning and end. Read an assembly tutorial for more details.