首页 > 代码库 > c语言到汇编的学习

c语言到汇编的学习

[内存结构]

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