> For the complete documentation index, see [llms.txt](https://legacy.cookielau.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://legacy.cookielau.com/archives/1-cpp/6-assembly.md).

# Assembly

## Layout

* .text：已编译程序的机器代码。
* .rodata：只读数据，比如printf语句中的格式串和开关（switch）语句的跳转表。
* .data：已初始化的全局C变量。局部C变量在运行时被保存在栈中，既不出现在.data中，也不出现在.bss节中。
* .bss：未初始化的全局C变量。在目标文件中这个节不占据实际的空间，它仅仅是一个占位符。目标文件格式区分初始化和未初始化变量是为了空间效率在：在目标文件中，未初始化变量不需要占据任何实际的磁盘空间。
* .symtab：一个符号表（symbol table），它存放在程序中被定义和引用的函数和全局变量的信息。一些程序员错误地认为必须通过-g选项来编译一个程序，得到符号表信息。实际上，每个可重定位目标文件在.symtab中都有一张符号表。然而，和编译器中的符号表不同，.symtab符号表不包含局部变量的表目。
* .rel.text：当链接噐把这个目标文件和其他文件结合时，.text节中的许多位置都需要修改。一般而言，任何调用外部函数或者引用全局变量的指令都需要修改。另一方面调用本地函数的指令则不需要修改。注意，可执行目标文件中并不需要重定位信息，因此通常省略，除非使用者显式地指示链接器包含这些信息。
* .rel.data：被模块定义或引用的任何全局变量的信息。一般而言，任何已初始化全局变量的初始值是全局变量或者外部定义函数的地址都需要被修改。
* .debug：一个调试符号表，其有些表目是程序中定义的局部变量和类型定义，有些表目是程序中定义和引用的全局变量，有些是原始的C源文件。只有以-g选项调用编译驱动程序时，才会得到这张表。
* .line：原始C源程序中的行号和.text节中机器指令之间的映射。只有以-g选项调用编译驱动程序时，才会得到这张表。
* .strtab：一个字符串表，其内容包括.symtab和.debug节中的符号表，以及节头部中的节名字。字符串表就是以null结尾的字符串序列。

![](https://cdn.jsdelivr.net/gh/CookieLau/imghost/img/20200814104936.png)

## Tools

### Linux: objdump

```bash
// 从 object file(.obj) 中反汇编 
objdump -d main.o

// 从 可执行文件 中反汇编
objdump -S a.out
// 注：只是尽可能反汇编，可执行文件生成时使用-g参数效果更好
```

## Reference

1. [csdn | Linux：objdump命令解析](https://blog.csdn.net/q2519008/article/details/82349869)
2. [kongfy | 探索C++虚函数在g++中的实现](http://blog.kongfy.com/2015/08/%E6%8E%A2%E7%B4%A2c%E8%99%9A%E5%87%BD%E6%95%B0%E5%9C%A8g%E4%B8%AD%E7%9A%84%E5%AE%9E%E7%8E%B0/)
