[内存结构]
C程序通过编译-汇编-连接,最后到可执行文件。载入内存有这几个部分:
text:正文段,存放的是可执行的机器码段
data:存放初始化之后的全局变量和静态变量
bbs:存放未初始化的静态变量和全局变量
heap:堆,由程序员自己分配和释放,程序结束时,操作系统也会释放。
stack: 栈,编译器自动分配,存放函数的参数,局部变量
下图是典型的内存布局图
#include <stdio.h>
#include <stdlib.h>
void foo(int x){printf("hello");}
typedef void(*FunCall)(int);
typedef struct{
FunCall b;
char c;
int a;
}AA;int main(){
AA aa;
aa.c = ‘s‘;
aa.a = 7;
aa.b = foo;
(*(aa.b))(aa.a);
return 0;
}
这是一个很简单的程序, 使用GCC编译选项编译成AT&T语法的汇编语言
gcc -S test1.c
下面来分析汇编代码
1 .file "test1.c"
2 .section .rodata
3 .LC0:
4 .string "hello"
5 .text
6 .globl foo
7 .type foo, @function
8 foo:
9 .LFB0:
10 .cfi_startproc
11 pushq %rbp
12 .cfi_def_cfa_offset 16
13 movq %rsp, %rbp
14 .cfi_offset 6, -16
15 .cfi_def_cfa_register 6
16 subq $16, %rsp
17 movl %edi, -4(%rbp)
18 movl $.LC0, %eax
19 movq %rax, %rdi
20 movl $0, %eax
21 call printf
22 leave
23 .cfi_def_cfa 7, 8
24 ret
25 .cfi_endproc
26 .LFE0:
27 .size foo, .-foo
28 .globl main
29 .type main, @function
30 main:
31 .LFB1:
32 .cfi_startproc
33 pushq %rbp
34 .cfi_def_cfa_offset 16
35 movq %rsp, %rbp
36 .cfi_offset 6, -16
37 .cfi_def_cfa_register 6
38 subq $16, %rsp
39 movb $115, -8(%rbp)
40 movl $7, -4(%rbp)
41 movq $foo, -16(%rbp)
42 movq -16(%rbp), %rdx
43 movl -4(%rbp), %eax
44 movl %eax, %edi
45 call *%rdx
46 movl $0, %eax
47 leave
48 .cfi_def_cfa 7, 8
49 ret
50 .cfi_endproc
51 .LFE1:
52 .size main, .-main
53 .ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
54 .section .note.GNU-stack,"",@progbits
以点开头的是汇编指示。
指令介绍
寄存器介绍
函数调用
汇编生成
gcc -g -c test.c
objdump -d -M intel -S test.o
时间: 2024-10-11 23:02:40