Gcc工具链常见参数详解

 
Category: C++

写在前面

单文件编译

#include <cstdio>
#define out(x) printf(x)

int main(int argc, char *argv[]) {
    const int a [[maybe_unused]] = 7; // stdc++17
    out("hello cpp\n");
    return 0;
}

预处理-E

  g++ -E aa.cpp -o aa.i
  # cpp aa.cpp > aa.i # 或者用 cpp 预处理器 (The C Preprocessor)

aa.i的部分结果:

# 4 "aa.cpp"
int main(int argc, char *argv[]) {
    const int a [[maybe_unused]] = 7;
    printf("hello cpp\n");
    return 0;
}

步骤:

  1. 去掉注释
  2. 展开宏

汇编-S

  g++ -S aa.i -o aa.s
	.file	"aa.cpp"
	.text
	.section	.rodata
.LC0:
	.string	"hello cpp"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$32, %rsp
	movl	%edi, -20(%rbp)
	movq	%rsi, -32(%rbp)
	movl	$7, -4(%rbp)
	leaq	.LC0(%rip), %rdi
	call	puts@PLT
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	 1f - 0f
	.long	 4f - 1f
	.long	 5
0:
	.string	 "GNU"
1:
	.align 8
	.long	 0xc0000002
	.long	 3f - 2f
2:
	.long	 0x3
3:
	.align 8
4:

编译-c

g++ -c aa.s -o aa.o

看一下具体信息:

$ file aa.o
aa.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

看符号表:

nm aa.o

                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U puts

链接

g++ aa.o -o main

 ./main
hello cpp

查看段信息

objdump

$ objdump -h aa.o

aa.o:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0000002d  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  0000006d  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  0000006d  2**0
                  ALLOC
  3 .rodata       0000000a  0000000000000000  0000000000000000  0000006d  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002c  0000000000000000  0000000000000000  00000077  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000a3  2**0
                  CONTENTS, READONLY
  6 .note.gnu.property 00000020  0000000000000000  0000000000000000  000000a8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .eh_frame     00000038  0000000000000000  0000000000000000  000000c8  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

-d:

aa.o:     file format elf64-x86-64

Contents of section .text:
 0000 f30f1efa 554889e5 4883ec20 897dec48  ....UH..H.. .}.H
 0010 8975e0c7 45fc0700 0000488d 3d000000  .u..E.....H.=...
 0020 00e80000 0000b800 000000c9 c3        .............
Contents of section .rodata:
 0000 68656c6c 6f206370 7000               hello cpp.
Contents of section .comment:
 0000 00474343 3a202855 62756e74 7520392e  .GCC: (Ubuntu 9.
 0010 342e302d 31756275 6e747531 7e32302e  4.0-1ubuntu1~20.
 0020 30342e31 2920392e 342e3000           04.1) 9.4.0.
Contents of section .note.gnu.property:
 0000 04000000 10000000 05000000 474e5500  ............GNU.
 0010 020000c0 04000000 03000000 00000000  ................
Contents of section .eh_frame:
 0000 14000000 00000000 017a5200 01781001  .........zR..x..
 0010 1b0c0708 90010000 1c000000 1c000000  ................
 0020 00000000 2d000000 00450e10 8602430d  ....-....E....C.
 0030 06640c07 08000000                    .d......

参数:

  • -d: 反汇编
  • -s: 十六进制输出

size

$ size aa.o
   text	   data	    bss	    dec	    hex	filename
    143	      0	      0	    143	     8f	aa.o

所以局部的常量(文件中的常整型 a=7)位于text 段, 也就是代码段, 当然也包括其他一些常量.