写在前面
单文件编译
#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;
}
步骤:
- 去掉注释
- 展开宏
汇编-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 段, 也就是代码段, 当然也包括其他一些常量.