Reputation: 103
i have written a c program for printing the arguments
#include<stdio.h>
void main( int argc, char *argv[])
{
int i=0;
for(i=0;i<argc;i++)
printf("argument %d=%s\n",i,argv[i]);
}
The assembly dump for the above program using gdb i got is.
Dump of assembler code for function main:
0x00000000004004f4 <+0>: push %rbp
0x00000000004004f5 <+1>: mov %rsp,%rbp
0x00000000004004f8 <+4>: sub $0x20,%rsp
0x00000000004004fc <+8>: mov %edi,-0x14(%rbp)
0x00000000004004ff <+11>: mov %rsi,-0x20(%rbp)
0x0000000000400503 <+15>: movl $0x0,-0x4(%rbp)
0x000000000040050a <+22>: movl $0x0,-0x4(%rbp)
0x0000000000400511 <+29>: jmp 0x40053e <main+74>
0x0000000000400513 <+31>: mov -0x4(%rbp),%eax
0x0000000000400516 <+34>: cltq
0x0000000000400518 <+36>: shl $0x3,%rax
0x000000000040051c <+40>: add -0x20(%rbp),%rax
0x0000000000400520 <+44>: mov (%rax),%rdx
0x0000000000400523 <+47>: mov $0x40063c,%eax
0x0000000000400528 <+52>: mov -0x4(%rbp),%ecx
0x000000000040052b <+55>: mov %ecx,%esi
0x000000000040052d <+57>: mov %rax,%rdi
0x0000000000400530 <+60>: mov $0x0,%eax
0x0000000000400535 <+65>: callq 0x4003f0 <printf@plt>
0x000000000040053a <+70>: addl $0x1,-0x4(%rbp)
0x000000000040053e <+74>: mov -0x4(%rbp),%eax
0x0000000000400541 <+77>: cmp -0x14(%rbp),%eax
0x0000000000400544 <+80>: jl 0x400513 <main+31>
0x0000000000400546 <+82>: leaveq
0x0000000000400547 <+83>: retq
End of assembler dump.
Now what i want is " The memory locations (addresses) at which the argument is passing. for eg if i run the program as " arg 1" it prints the arguments. Now I want to know on which instruction it is extracting this argument ,or which register holds the arguments (also take the case if i pass more than 1 argument.. (will this tell me the memory address on which it resides?)
Upvotes: 0
Views: 3954
Reputation: 16406
I want to know on which instruction it is extracting this argument ,or which register holds the arguments
This sort of question is best answered by obtaining an assembly language reference manual for the target machine and studying it. However, your specific questions are easily answered by examination without being very familiar with the specifics of the assembly language:
0x0000000000400503 <+15>: movl $0x0,-0x4(%rbp)
0x000000000040050a <+22>: movl $0x0,-0x4(%rbp)
This is the code generated for the redundant i = 0
statements.
0x0000000000400513 <+31>: mov -0x4(%rbp),%eax
The value of i
is now in the %eax register.
0x0000000000400518 <+36>: shl $0x3,%rax
0x000000000040051c <+40>: add -0x20(%rbp),%rax
This calculates the address of argv[i]
and puts it in the %rax register.
0x0000000000400520 <+44>: mov (%rax),%rdx
This loads the value of argv[i]
into the %rdx register. Code following calls printf
with i
and argv[i]
as arguments.
Now what i want is " The memory locations (addresses) at which the argument is passing.
You can no more determine that by looking at the asm than you can determine the value of argc by looking at the asm ... these are values that vary and are only determined when actually running the program. If you want to determine the address at runtime, you could use
printf("address of argv = %p\n", (void*)argv);
If that's what you want, then dumping asm and learning what it means is unnecessary and not relevant to your goal.
Upvotes: 2
Reputation: 1
Since you are using gdb
to debug, I guess you might use Linux. Then, use gcc -S -Wall -fverbose-asm foo.c
(possibly with optimization flags like -O2
) to get a more understandable foo.s
assembly file, assuming your file is foo.c
(if it is hello.c
replace foo
by hello
). Then look inside foo.s
with an editor (like gedit
or emacs
).
And main
is almost an ordinary function (except its signature has to be what is permitted by the standard, e.g. int main(int argc, char**argv)
....) and it is called by crt0.o
(compile with gcc -v
to learn which one).
You might want to read the Linux Assembly Howto and e.g. the x86-64 ABI and the x86 calling convention wikipage.
Notice that without any optimization flags (e.g. -O1
or -O2
) the gcc
compiler generates very naive code.
Upvotes: 1