分析.cpp文件编译生成的汇编文件里语句的作用
1
2
3
4
|
int
main(
int
argc,
char
** argv)
{
return
1;
}
|
1
|
g++ -S
test
.cpp
|
生成test.s汇编文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
.file
"null-test.cpp"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $1, %eax
popq %rbp
.cfi_def_cfa 7, 8 ret
.cfi_endproc
//在函数结束的时候使用与.cfi_startproc相配套使用
.LFE0:
.size main, .-main
.ident
"GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,
""
,@progbits
|
看到上面有一些语句如
cfi_def_cfa cfi_endproc cfi_startproc的命令,这些前面都有个关键字cfi 它是Call Frame infromation的意思。
查看堆栈的信息
CFA是什么意思就不太清楚了 可能是control flow analysis的意思吧?
.cfi_startproc 用在每个函数的开始,用于初始化一些内部数据结构
.cfi_endproc 在函数结束的时候使用与.cfi_startproc相配套使用
.cfi_def_cfa_offset 16
12.cfi_def_cfa_offset offset
.cfi_def_cfa_offset modifies a rule for computing CFA. Register remains the same, but offset is new. Note that it is the absolute offset that will be added to a defined register to compute CFA address.
.cfi_def_cfa 7, 8
12.cfi_def_cfa register, offset
.cfi_def_cfa defines a rule for computing CFA as: take address from register and add offset to it.
.cfi_def_cfa_register 6
12.cfi_def_cfa_register register
.cfi_def_cfa_register modifies a rule for computing CFA. From now on register will be used instead of the old one. Offset remains the same.
.cfi_offset 6, -16
123.cfi_offset register, offset
Previous value of register is saved at offset offset from CFA.
.cfi_startproc 和 .cfi_endproc 分别是 dwarf2 CFI 的初始过程和结束过程指令,它们隐藏了一些 CFI 有关的操作。ret 是从当前过程中返回的指令。这就是一个最简单的 main 函数内部的三个步骤:CFI 初始操作 – 返回 – CFI 结束操作。由于第一个和最后一个步骤永远伴随着函数,我们大可将注意力集中在这两个步骤之间的代码,也就是 main 函数的实际内容。
eax 是一个通用的寄存器,根据 cdesl 调用约定(即 C 语言调用约定),在函数返回时,返回值必须保存在 eax 寄存器中,交给调用者处理。
rbp寄存器 是ebp寄存器64位扩展,ebp寄存器扩展基址指针寄存器(extended base pointer) 其内存放一个指针,该指针指向系统栈最上面一个栈帧的底部。BP
为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据,它的作用是在调用函数时保存ESP使函数结束时可以正确返回;加E(enhance)代表增强型寄存器,用于32位数据处理。
EAX也是一种32位通用寄存器。 EAX寄存器称为累加器,AX寄存器是算术运算的主要寄存器,所有的输入、输出只使用AL或AX人作为数据寄存器。在80386及其以上的微处理器中,EAX寄存器可以用来存储单元的偏移地址。
将数据33221100H传送到EAX寄存器的指令
EAX可称为数据寄存器,你除了直接访问外,还可分别对其高十六位和低十六位进行访问。它们的低十六位就是把它们前边儿的E去掉,即EAX的低十六位就是AX。而且它们的低十六位又可以分别进行八位访问,也就是说,AX还可以再进行分解,即AX还可分为AH(高八位)AL(低八位)。
.file
, .text
, etc are assembler directives.
.LFB0
, .LFE0
are local labels, which are normally used as branch destinations within a function.