Linux内核分析课程学习笔记1--汇编一个简单的C程序,分析汇编代码理解计算机是如何工作

陈琛 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程

1.在Linux环境下编译如下程序

int g(int x)
{
  return x + 4;
}

int f(int x)
{
  return g(x);
}

int main(void)
{
  return f(5) + 1;
}

2.编译出汇编代码

gcc –S –o main.s main.c -m32

编译出来,经过精简的汇编代码如下:

image

3.汇编代码分析

  • (1)main

1)栈初始化示意图:

image

2)

pushl %ebp        ;将ebp压入栈顶
movl %esp, %ebp   ;以上两条代码,构建一个新的函数栈环境
                  ;执行完效果如下图所示

image

3)

subl	$4, %esp    ;栈顶esp指针减4
movl	$5, (%esp)  ;立即数5放入esp指向的位置
                    ;执行完以上两条指令效果如下图所示

image

1)

call f              ;调用f函数,相当于
                    ;pushl eip  把eip压入栈(保存返回的地址),此时eip指向call的下一条指令(addl $1 %eax)
                    ;movl f eip f函数的地址放入eip
                    ;栈示意图如下

image

  • (2)f函数执行过程分析

1)

pushl %ebp        
movl %esp, %ebp  ;同理,构造f函数栈环境
                 ;执行完效果如下图

image

2)

subl $4, %esp
movl 8(%ebp), %eax  ;ebp+8(变址寻址存储立即数5的地址),然后把5送入到eax寄存器
movl %eax, (%esp)   ;5送入到esp指向的位置
                    ;参数传递,执行完效果如下图

image

3)

call g              ;调用g函数
                    ;pushl eip eip目前指向代码15行代码
                    ;movl g eip  eip指向g函数的位置

image

  • (3)g函数执行过程分析

1) 构造g函数栈环境

pushl %ebp
movl %esp, %ebp

image

2)

movl 8(%ebp), eax   ;ebp变址寻址,将5放入eax
addl $4, eax        ;立即数3与eax内容相加得到9,放入eax

image

3)

popl %ebp       ;栈顶出栈,存入ebp寄存器
                ;目前栈顶为地址ebp15,也就是让ebp指向地址为15的位置

image

4)

ret         ;相当于popl %eip, 所以eip现在指向代码15行
            ;即回到调用者f函数的leave指令

image

  • (4)g函数返回到f函数

1) leave

leave       ;movl %ebp, %esp
            ;popl %ebp

image

2) ret

ret         ; popl %eip
            ;eip指向代码23行,返回到主函数call f指令后一条指令

image

  • (4)f函数返回到main函数

1)

addl $1, %eax   ; eax寄存器内容与立即数1相加,结果放在eax中

2)

leave   ;movl %ebp, %esp
        ;popl %ebp

image

3)

ret     ;

4. 重点记录

(1) leave指令

(2) ret指令

(3) eip寄存器的作用

(4) eax寄存器的作用

(5) popl, pushl 指令以及相关的寄存器ebp, esp

5.心得体会

通过分析这一段汇编程序,对函数调用过程以及参数传递理解更加清晰。

posted @ 2017-02-26 18:06  tb1over  阅读(139)  评论(0)    收藏  举报