一.C语言程序进行汇编,分析其过程 1.使用vim 20222801.c的命令创建一个c语言程序,并为文件添加一下代码
// main.c
int g(int x)
{
return x + 3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8) + 1;
}
通过ls *** 作后可以查看到已经生成了2022801.s的汇编文件
2.查看汇编文件,并分析过程cat 20222801.s
汇编文件中有一些“.cfi_”打头的字符串其他以"."打头的字符串,这些都是在编译器链接阶段所需要的辅助信息,这些辅助信息都可以删掉,可以在VIM中使用“g^.s*/d”命令删除所有以“.”打头的字符串,这样就可以获得干净的代码
sed -i '/[.]/d' 20222801.s //第二种清理"."打头的字符串
“清理”之后,再次查看20222801.s文件
main函数
汇编指令 | 作用 |
---|---|
pushl %ebp | 将EBP(栈基值)寄存器的值入栈 |
movl %esp,%ebp | EBP指针指向标号1的位置 |
subl ,%esp | ESP指针向下增1,指向下一个标号位置 |
movl , (%esp) | 将立即数8放入ESP寄存器指向的标号2位置 |
call f | 调用g函数,先将ESP后移,存储现在EIP寄存器内的值,然后EBP内的值压榨存储到下一标号位置 |
接着开始执行f函数
汇编指令 | 作用 |
---|---|
pushl %ebp | 把ESP寄存器的值向下移到标号4 |
movl %esp, %ebp | 把EBP寄存器的值标号1放到栈空间标号4的位置 |
subl ,%esp | ESP寄存器指针向下加1,指向下一个标号位置 |
movl 8(%ebp), %eax | 把立即数8放到EAX的寄存器 |
movl %eax,( %esp) | 将EAX寄存器里的值放到ESP所指的位置 |
call g | 调用g函数,先将ESP后移,存储现在EIP寄存器内的值,然后EBP内的值压榨存储到下一标号位置 |
接着开始执行g函数
汇编指令 | 作用 |
---|---|
pushl %ebp | 将EBP(栈基值)寄存器的值入栈 |
movl %esp, %ebp | 让EBP和ESP指向同一个位置 |
movl 8(%ebp), %eax | 将EBP指针前两个标号位置的内容放入EAX运算单元内 |
addl ,%eax | 将EAX内的值+3 |
pool %ebp | 将标号7放入EBP寄存器里,让EBP指针回归上一级函数的栈底 |
ret | 函数返回,将标号6内的值放入EIP寄存器内 |
返回f函数中的第15条命令
汇编指令 | 作用 |
---|---|
leave | 销毁f函数的这一部分工作站栈 |
ret | 函数返回,将标号3内的值放入EIP寄存器内 |
返回main函数的第23条命令
汇编指令 | 作用 |
---|---|
addl ,%eax | 将EAX中内容加1,EAX寄存器是默认存储函数返回值的寄存器 |
leave | 销毁main函数工作栈 |
ret | 函数返回 |
①刚开始不能连贯理解汇编的过程每一步,有一些基础的概念弄不清。
②对一些有复合步骤的汇编指令如:call f,leave,ret等,对其细化的过程的理解还不是很清晰。
不懂的概念查阅教材资料,然后自己在草稿纸上跟着各指令完整走一遍之后就得到了更为清晰的理解。
20222801 余酋龙
2022 年 09月 25日
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)