g++二进制输出分析
g++ binary output analysis
给定以下程序:
unsigned char g1[] = { 0x1a, 0x2a, 0x3a, 0x4a };
static unsigned char g2[] = { 0x1b, 0x2b, 0x3b, 0x4b };
int main()
{
unsigned char l1[] = { 0x1c, 0x2c, 0x3c, 0x4c };
static unsigned char l2[] = { 0x1d, 0x2d, 0x3d, 0x4d };
}
之后,简单地用"g++ test.cpp -o test"编译它,并在二进制文件上运行hexdump -C,我意识到g1, g2和l2的序列可以在二进制文件上清晰地找到。只有l1 (1c 2c 3c 4c)的序列在二进制文件中显然没有出现。
有人知道这是为什么吗?
因为它是在该函数调用的堆栈上分配的。通常在这种情况下,会发生以下两种情况之一:
-
编译器将将该序列存储在数据段中,然后基本上将其memcpy到堆栈缓冲区中。
-
编译器本质上是硬编码"move"指令,从指令集(通常是4字节整型)的最大直接值重新组装序列。
如果它没有被优化,就像前面提到的"unwind"一样,那么#2可能会发生。看看反汇编程序(或预汇编的asm代码)会更好。使用-S
并查看.s文件。
我的猜测是,因为它是非static
和自动的(非全局的),所以知道没有人能够从外部引用它是微不足道的。
l1[]
和l2[]
在编译器优化期间被删除,因为它们都是local and unused variables
(没有机会这两个变量将在其他任何地方使用)。
你可以用-S
选项编译你的代码来生成汇编代码:并且在main中没有l1[]
和l2[]
的定义,甚至在其他任何地方都没有:
输入文件为x.c
,用gcc -S x.c
命令编译生成汇编文件x.s
main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movb $28, -4(%ebp)
movb $44, -3(%ebp)
movb $60, -2(%ebp)
movb $76, -1(%ebp)
leave
ret
.size main, .-main
.data
.type l2.1250, @object
.size l2.1250, 4
但是你可以找到g1[] and g2[]
的定义。
.file "x.c"
.globl g1
.data
.type g1, @object
.size g1, 4
g1:
.byte 26
.byte 42
.byte 58
.byte 74
.type g2, @object
.size g2, 4
g2:
.byte 27
.byte 43
.byte 59
.byte 75
.text
.globl main
.type main, @function
另外,如果你用标志-O3
优化标志级别3编译你的代码,那么只有g1[]
的定义是存在的,这将是有趣的。全局静态变量(文件私有)也被删除。
输入文件为x.c
,用gcc -S -O3 x.c
命令编译生成汇编文件x.s
:
.file "x.c"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.size main, .-main
.globl g1
.data
.type g1, @object
.size g1, 4
g1:
.byte 26
.byte 42
.byte 58
.byte 74
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",@progbits
g1[]
是仅存在的全局数据,g2[]
在-O3
中被删除。
g2[]
使用已定义的static unsigned char g2[]
,所以只能访问这个文件,不能再次使用。但是g1[]
是全局的,如果其他文件包含它,它可能对其他程序有用。编译器不允许优化全局对象。
参考:我如何防止我的"未使用的"全局变量被编译出来?
所以,这都是由于编译器优化!
- 二进制搜索不适用于特定输出
- 输入 1024 后十进制到二进制转换的输出错误?
- 读取二进制文件时如何输出?
- 编译器将输出的流运算符<<解释为用于按位左移的二进制运算符<<
- C++实现代码中的字符串不应存在于输出二进制文件中.如何解决
- qDebug - 如何以位(二进制格式)输出数据
- 在C 中输出到二进制文件中的麻烦
- 如何获取与 objdump 输出的标签相对应的 ELF 二进制文件中的文件偏移量
- 二进制搜索 - 代码编译并运行后不显示输出
- Z3 C++ API 产生"unknown",而序列化输出上的二进制生成"unsat"
- 具有特征类型输出的特征二进制 Expr
- 读取并输出二进制文件(C++)中位置的字节
- 在线C++编译器:为我输出二进制文件
- 如何在 C++ 中使用更改光标输入和输出二进制文件
- 输出二进制数据缺少一些字节
- C++ 使用 "putchar" 输出二进制单词
- 自动使输出二进制文件大于命令行编译的二进制文件
- Linux CGI Web API -如何在c++下输出二进制JPEG图像
- 为什么这段代码不产生输出?c++二进制搜索使用xcode
- 有没有一种方法可以在输出二进制文件中存储clang编译时标志