GNU相关介绍

本文将逐渐转移

GCC

常用选项

-Og 执行所有不影响调试体验的优化[4]
-Wall 使能所有的警告
-ffunction-sections 将每个函数放入自己的段中
-fdata-sections 将每个数据放入自己的段中
-x assembler-with-cpp 其格式为:-x language。为输入文件指定语言(而不是让编译器根据后缀选择默认语言)
-u_scanf_float 在scanf中使用f%
-u_printf_float 在printf中使用f%

预处理

-E	Preprocess only; do not compile, assemble or link.
-E	仅预处理; 不要编译、汇编或链接。

gcc -E main.c -o main.i

编译

-S	Compile only; do not assemble or link.
-S	仅编译; 不要汇编或链接。

gcc -S main.c -o main.s

汇编

-c	Compile and assemble, but do not link.
-c	编译和汇编,但不要链接。

gcc -c main.c -o main.o

链接

链接文件
编译命令
gcc main.o -o main

指定头文件路径

https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gcc.pdf	第265页

gcc main.c -I inc -o main

生成依赖关系

https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gcc.pdf	第252页

gcc -MM main.c -I inc/

输出:
main.o: main.c inc/inc.h

readelf工具

添加代码:

static const char __attribute__((section(".test.str"))) str[] = "hello word!\n";

执行: readelf -S xxx

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .isr_vector       PROGBITS        08000000 0000b8 000040 00   A  0   0  1
  [ 2] .text             PROGBITS        08000040 0000f8 00f33c 00  AX  0   0  8
  [ 3] .rodata           PROGBITS        0800f37c 00f434 004190 00   A  0   0  4
  [ 4] .test.str         PROGBITS        0801350c 0135c4 00000d 00   A  0   0  4

0801350c(Addr):若可被加载,则对应虚拟地址。如下为bin文件的地址,如被加载则为虚拟地址0801350c,物理地址一般和虚拟地址一样。
bin文件地址
0135c4(Off):在文件中的偏移地址,对.bss段而言则无意义。如下为elf文件的地址。
elf文件地址

00000d(Size):表示该段的大小,str字符串0x0d字节。
Flg:表示权限,RE表示只读,RW表示可读可写。
Align:表示映射到虚拟地址后的对齐方式。

objdump工具

执行: objdump --section=.test.str -s main
-s --full-contents:显示指定section的完整内容。默认所有的非空section都会被显示。[3]

Contents of section .test.str:
 0798 68656c6c 6f31210a 00000000 00000000  hello1!.........
 07a8 68656c6c 6f32210a 00000000 00000000  hello2!.........
 07b8 68656c6c 6f33210a 00                 hello3!..       

执行:objdump -j .text -S main
反汇编main中的text段内容,并尽可能用源代码形式表示。

参考文献

[1] 计算机系统基础目标文件格式
https://www.codenong.com/cs106511100/
[2] readelf(1) — Linux manual page
https://www.man7.org/linux/man-pages/man1/readelf.1.html
[3] objdump命令详解
https://blog.csdn.net/qq_41683305/article/details/105375214
[4] gcc“你好,世界!” 具有常见的命令行选项
https://www.nhooo.com/note/qa54zx.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张暮笛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值