C ++-helloworld [1]

Source: Internet
Author: User

My experiment environment:

1. cygwin: runs on Windows. If you do not have this environment, see http://www.cygwin.com/to install and configure the environment.

2. GCC family of tools: compilation/decompilation and analysis, including GCC, G ++, objdump, As, nm, LD, etc.

 

Now, start the first entry program. Without exception, we use the classic helloworld program named helloworld. cpp. The content is as follows:

 

# Include <cstdio>
Int main (INT argc, char ** argv)
{
Printf ("Hello World/R/N ");
Return 0;
}

 

Run

G ++-O helloworld. cpp

The executable file helloworld is generated in the current directory.

./Helloworld

The output is displayed.

Hello World

 

Very simple, right!

 

Next, run

G ++-O helloworld. cpp-Save-temps

Note that a new compilation option-save-temps is added here. This option tells the compiler, "Hi, buddy! Save all the intermediate files during the compilation process! Do not delete or delete !". Okay. What files are in the current directory?

Helloworld. O -- this is the object file before the link compiled by helloworld. cpp.

Helloworld. II -- this is the file after the compiler expands the source code. It mainly copies the content of other referenced header files and expands and replaces the Macros in the code, replace a constant value and perform other basic code expansion operations.

Helloworld. s -- this is the assembly code file before the object is generated.

 

View helloworld. II, enter

Vim helloworld. II

You will see the content in it, which is listed here:

#598 "/usr/include/stdio. H" 3 4
}
#53 "/usr/lib/GCC/i686-pc-cygwin/3.4.4/include/C ++/cstdio" 2 3
#97 "/usr/lib/GCC/i686-pc-cygwin/3.4.4/include/C ++/cstdio" 3
Namespace std
{
Using: file;
Using: fpos_t;

Using: clearerr;
Using: fclose;
Using: feof;
Using: ferror;
Using: fflush;
Using: fgetc;
Using: fgetpos;
Using: fgets;
Using: fopen;
Using: fprintf;
Using: fputc;
Using: fputs;
Using: fread;
Using: freopen;
Using: fscanf;
Using: fseek;
Using: fsetpos;
Using: ftell;
Using: fwrite;
Using: GETC;
Using: getchar;
Using: gets;
Using: perror;
Using: printf;
Using: putc;
Using: putchar;
Using: puts;
Using: Remove;
Using: Rename;
Using: rewind;
Using: scanf;
Using: setbuf;
Using: setvbuf;
Using: sprintf;
Using: sscanf;
Using: tmpfile;
Using: tmpnam;
Using: ungetc;
Using: vfprintf;
Using: vprintf;
Using: vsprintf;
}
#2 "helloworld. cpp" 2

Int main (INT argc, char ** argv)
{
Printf ("Hello world-fengyanshuo./R/N ");
Return 0;
}


As you can see, this file only extends the Code. There is no substantial change.

View the file helloworld. s and enter

Vim helloworld. s


Haha, see it. Here is the assembly code:

1. File "helloworld. cpp"
2. Def ___ main;. SCL 2;. Type 32;. endef
3. Section. RDATA, "Dr"
4 lc0:
5. ASCII "Hi world-fengyanshuo./15/12/0"
6. Text
7. Align 2
8. globl _ main
9. Def _ main;. SCL 2;. Type 32;. endef
10_main:
11 pushl % EBP
12 movl % ESP, % EBP
13 subl $8, % ESP
14 andl $-16, % ESP
15 movl $0, % eax
16 addl $15, % eax
17 addl $15, % eax
18 shrl $4, % eax
19 Sall $4, % eax
20 movl % eax,-4 (% EBP)
21 movl-4 (% EBP), % eax
22 call _ alloca
23 call ___ main
24 movl $ lc0, (% ESP)
25 call _ printf
26 movl $0, % eax
27 leave
28 RET
29. Def _ printf;. SCL 2;. Type 32;. endef


 

In the first line, it is obvious that this is generated by helloworld. cpp or the source code is helloworld. cpp.

In the second line,. Def _ main refers to a function called _ main. Note that this is not the main function. This is the first function called before entering the main function.

Followed by the read-only data segment. Obviously, the string to be printed is placed in it.

Next, declare the function _ main. Note that this is the real main function, followed by the implementation of the main function from the label _ main: to the 28 rows.

Row 3 declares the function _ printf, which is actually the printf function in the Standard C ++ library.

Obviously, only the main function is implemented, and the _ main and _ printf are not implemented. This requires the linker to find the required function from other objects in the Link phase, then allocate the address.

 

Well, focus on the implementation of the main function:

Pushl % EBP

Movl % ESP, % EBP

These two statements are typical GCC compilers that use function call entry operations. GCC uses the EBP register as the base address register, and the function entry needs to implement the rollback stack. Function roll-out requires rollback; the ESP content will be sent to EBP. Later, the EBP register will be used inside the function to perform stack operations in the function to access function parameters and process local variables in the function.

In row 3, it is not clear to call _ alloca. It is estimated that it applies for space for the stack, and then calls the _ main function, and then passes

Movl $ lc0, (% ESP)

Send the string address to the address indicated by the ESP register. Call the function _ printf and _ printf to perform the register stack operation, obtain the passed string parameters through the ESP register, and then perform the output operation.

In row 3, the number 0 is sent to the Register eax, and then the program returns it. GCC uses eax to store the return value of the function. Basically, all functions finally send the result to eax and then return it.

 

How can I get a deeper understanding of the compilation process and results by looking at the compiled assembly?

 

Next, let's take a look at what is in helloworld. O? Helloworld. O is actually a file in ELF format. To put it bluntly, it is an executable file format that can be linked. Run:

$ Objdump.exe-D helloworld. o

Helloworld. O: File Format pe-i386

Disassembly of section. Text:

00000000 <_ main>:
0: 55 push % EBP
1: 89 E5 mov % ESP, % EBP
3: 83 EC 08 Sub $0x8, % ESP
6: 83 E4 F0 and $0xfffffff0, % ESP
9: B8 00 00 00 mov $0x0, % eax
E: 83 C0 0f add $ 0xf, % eax
11: 83 C0 0f add $ 0xf, % eax
14: C1 E8 04 SHR $0x4, % eax
17: C1 E0 04 SHL $0x4, % eax
1a: 89 45 FC mov % eax,-0x4 (% EBP)
1D: 8B 45 FC mov-0x4 (% EBP), % eax
20: E8 00 00 00 call 25 <_ main + 0x25>
25: E8 00 00 00 call 2a <_ main + 0x2a>
2a: C7 04 24 00 00 00 00 movl $0x0, (% ESP)
31: E8 00 00 00 call 36 <_ main + 0x36>
36: B8 00 00 00 mov $0x0, % eax
3B: C9 leave
3c: C3 RET
3D: 90 NOP
3E: 90 NOP
3f: 90 NOP

Disassembly of section. RDATA:

00000000 <. RDATA>:
0: 48 dec % eax
1: 65 GS
2: 6C InSb (% dx), % es :( % EDI)
3: 6C InSb (% dx), % es :( % EDI)
4: 6f outsl % DS :( % Esi), (% dx)
5: 20 57 6f and % DL, 0x6f (% EDI)
8: 72 6C JB 76 <_ main + 0x76>
A: 64 FS
B: 2D 46 65 6e 67 sub $0x676e6546, % eax
10: 59 pop % ECx
11: 61 Popa
12: 6e outsb % DS :( % Esi), (% dx)
13: 73 68 Jae 7d <_ main + 0x7d>
15: 75 6f JNE 86 <_ main + 0x86>
17: 2E CS
18: 0d. byte 0xd
19: 0a 00 or (% eax), % Al
...

 

The objdump tool decompile the ELF File to analyze each segment in the ELF File for reverse analysis. As you can see, for the main function, the object file is almost the same as that in helloworld. S, but there will be some differences in the read-only data segment.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.