ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
I wrote a simple C program to test the memory allocation for local variables.
Code:
#include <stdio.h>
int main(int argc, char **argv) {
int x=10;
return 0;
}
But when i try to disassemble the program using gdb, it shows that 16 bytes are being reserved for local variables on the stack, although i declared a single integer variable which is supposed to take only 4 bytes.
Can anyone tell, why it is reserving 16 bytes on the stack for just a single variable ?
Code:
Breakpoint 1, main () at test7.c:4
4 int x=10;
(gdb) disassemble main
Dump of assembler code for function main:
0x08048344 <main+0>: lea 0x4(%esp),%ecx
0x08048348 <main+4>: and $0xfffffff0,%esp
0x0804834b <main+7>: pushl 0xfffffffc(%ecx)
0x0804834e <main+10>: push %ebp
0x0804834f <main+11>: mov %esp,%ebp
0x08048351 <main+13>: push %ecx
0x08048352 <main+14>: sub $0x10,%esp
0x08048355 <main+17>: movl $0xa,0xfffffff8(%ebp)
0x0804835c <main+24>: mov $0x0,%eax
0x08048361 <main+29>: add $0x10,%esp
0x08048364 <main+32>: pop %ecx
0x08048365 <main+33>: pop %ebp
0x08048366 <main+34>: lea 0xfffffffc(%ecx),%esp
0x08048369 <main+37>: ret
End of assembler dump.
the compiler is free to do what it wants based on the best interests of the architecture, I woulfd GUESS the compiler is optimzing access to the int by aligning it on a 128 bit boundary in memory. 128 bits may also be best for a minimum size for a stack frame as well. I dunno.
if you want the size of a program stack you can call getrusage() to get stack size while it is running. the struct rusage member ru_isrss gives that information.
From the command line, size <compiled_file> will also give you information about your compiled image file.
What part of the disassembly indicates 16 bytes are on the stack?
Subroutine's memory are put on the stack and you have two primitive values that are arguments for the main function. These command line arguments will definitely need allocation. **argv, the argument vector variable is a double pointer as well.
Here is what I see that is going on in the disassembly: fff0, fffc, fff8, are address variables on the CPU. The CPU register, ECX is specifically used for counter variables, so it is related to argc, the argument count variable. The actions 'push %ecx' and 'pop %ecx' are pushing the variable onto the stack and popping it off of the stack. ESP is the stack pointer and points to the address of the stack at the point in the program. 0x08048344 <main+0>:, is an adress marker as well, through the disassembly you can see that the left hand address number in hexadecimal (base 16) and on the right it has the function's name as well as +0 (base 10). The left-hand number's two numbers at the right '44' will increment the same amount as the right hand number 'main +'. If you find a hex to decimal converter on the internet you can convert those hex numbers and see the increments are the same.
That is what I know about Assembly language, I hope it helps...
the compiler is free to do what it wants based on the best interests of the architecture, I woulfd GUESS the compiler is optimzing access to the int by aligning it on a 128 bit boundary in memory. 128 bits may also be best for a minimum size for a stack frame as well.
Yeah, may be. When i tried declaring 4 variables, the same 16 bytes of memory was allocated, but when i tried declaring 5 variables, 32 bytes of memory was allocated on the stack.
But now, when i declare a 100 byte char array, 116 bytes of memory is being allocated on the stack. Any idea, why ?
Code:
(gdb) list
1 #include <stdio.h>
2
3 int main(int argc, char **argv) {
4 char buf[100];
5
6 return 0;
7 }
8
(gdb) disassemble main
Dump of assembler code for function main:
0x080483a4 <main+0>: lea 0x4(%esp),%ecx
0x080483a8 <main+4>: and $0xfffffff0,%esp
0x080483ab <main+7>: pushl 0xfffffffc(%ecx)
0x080483ae <main+10>: push %ebp
0x080483af <main+11>: mov %esp,%ebp
0x080483b1 <main+13>: push %ecx
0x080483b2 <main+14>: sub $0x74,%esp
0x080483b5 <main+17>: mov 0x4(%ecx),%eax
0x080483b8 <main+20>: mov %eax,0xffffff88(%ebp)
0x080483bb <main+23>: mov %gs:0x14,%eax
0x080483c1 <main+29>: mov %eax,0xfffffff8(%ebp)
0x080483c4 <main+32>: xor %eax,%eax
0x080483c6 <main+34>: mov $0x0,%eax
0x080483cb <main+39>: mov 0xfffffff8(%ebp),%edx
0x080483ce <main+42>: xor %gs:0x14,%edx
0x080483d5 <main+49>: je 0x80483dc <main+56>
0x080483d7 <main+51>: call 0x80482e4 <__stack_chk_fail@plt>
0x080483dc <main+56>: add $0x74,%esp
0x080483df <main+59>: pop %ecx
0x080483e0 <main+60>: pop %ebp
0x080483e1 <main+61>: lea 0xfffffffc(%ecx),%esp
0x080483e4 <main+64>: ret
End of assembler dump.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.