反汇编一个简单的C程序#Linux内核分析
WuQi
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
1、C语言程序
1 int g(int x) 2 { 3 return x+54; 4 5 } 6 7 int f(int x) 8 { 9 return g(x); 10 11 } 12 13 int main(void) 14 { 15 return f(41) + 1; 16 17 }

2、编译成汇编语言
1 g: 2 pushl %ebp 3 movl %esp, %ebp 4 movl 8(%ebp), %eax 5 addl $54, %eax 6 popl %ebp 7 ret 8 f: 9 pushl %ebp 10 movl %esp, %ebp 11 subl $4, %esp 12 movl 8(%ebp), %eax 13 movl %eax, (%esp) 14 call g 15 leave 16 ret 17 main: 18 pushl %ebp 19 movl %esp, %ebp 20 subl $4, %esp 21 movl $41, (%esp) 22 call f 23 addl $1, %eax 24 leave 25 ret

3、对汇编程序进行分析
在main函数中, pushl %ebp//将当前的地址进行保存 movl %esp, %ebp//在堆栈里构建属于这个函数的堆栈 //这两句合在一起,一方面将当前的程序地址进行保存,另一方面将堆栈的基地址进行改变(我认为可以对基地址进行保护) subl $4, %esp//堆栈栈顶指针下移一个单位,为下面即将执行的指令挪出一个空间 movl $41, (%esp)//将41放入堆栈所指向的空间中 call f//程序调至函数f() f: pushl %ebp//将当前的地址进行保存 movl %esp, %ebp//在堆栈里构建属于这个函数的堆栈 subl $4, %esp//堆栈顶流出一个空间,给后边的movl %eax, (%esp)使用 movl 8(%ebp), %eax//ebp+8是输入参数所在的地址,8(%ebp)代指输入的参数的值。经过这一操作,将参数给赋到eax寄存器 movl %eax, (%esp)//将eax的值放入堆栈,供下面的函数g使用 call g g: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax//ebp+8是输入参数所在的地址,8(%ebp)代指输入的参数的值。经过这一操作,将参数给赋到eax寄存器 addl $54, %eax//进行计算 popl %ebp ret leave//需要恢复原栈顶指针,然后再根据栈顶指针恢复原栈帧的ebp,对应第一句的“pushl %ebp” ret addl $1, %eax leave ret
关于计算机工作的原理:
1、计算机使用寄存器记录程序的位置,索引程序进行
2、通过call、ret进行程序的调用和返回,实际就是变换第1点中的指针的内容
3、在调用程序时,使用堆栈的Push操作对现场进行保护
4、需要进行计算,就将数据输入到加法器(相应的寄存器)中,然后再将数据调回来
浙公网安备 33010602011771号