作者:Sandy 原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”
实验环境:c+Linux64位 (32位系统可能结果会不同)
依照学术诚信条款,我保证此回答为本人原创,所有回答中引用的外部材料已经做了出处标记。
———————————-大家好我是分割线————————————————
C源代码如下
/********************
main.c
*********************/
int g(int x)
{
return x + 2;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(7) + 1;
}
用如下命令将上述C程序编译成汇编代码:
gcc –S –o main.s main.c -m32
得到的汇编代码main.s的内容如下:
.file "main.c"
.text
.globl g
.type g, @function
g:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
addl $2, %eax
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size g, .-g
.globl f
.type f, @function
f:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size f, .-f
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $4, %esp
movl $7, (%esp)
call f
addl $1, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
其中以“.”开头的代码是下一步链接需要使用的,为了方便阅读汇编代码可以将其删除,得到的“纯”汇编代码如下:
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $2, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
ret
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $7, (%esp)
call f
addl $1, %eax
leave
ret
———————————————大家好我还是分割线—————————————————–
现在分析汇编代码的执行过程及堆栈的情况
首先,各寄存器的含义如下图所示:
常用的汇编语句含义如下:
*
注:图片截图自课程提供的课件,如欲详细了解寄存器相关知识请于网上课程下载课件,课程地址见最上方
*
下面是对汇编代码的图解分析:
动态流程图如下:
如果看不清楚还有单张图片:
最后执行返回汇编代码即可以结束该程序的运行。
*
依照学术诚信条款,我保证此博客为本人原创,所有引用的外部材料已经做了出处标记。
*