Linux用GCC和GDB对C语言进行汇编语言分析

前言
为能深入学习Linux,提高编程能力,探寻奇妙的编程之旅,参加了网易的《Linux内核分析》公开课。
卢晅 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
第一章 原文件处理

C语言源代码:
int a(int x)
{
  return x + 5;
}
 
int b(int x)
{
  return a(x);
}
 
int main(void)
{
  return  b(7) + 6;
}


得出的汇编代码:
a:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	addl	$5, %eax
	popl	%ebp
	ret
b:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	8(%ebp)
	call	a
	addl	$4, %esp
	leave
	ret
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	$7
	call	b
	addl	$4, %esp
	addl	$6, %eax
	leave


第二章 调试
实验环境为:Ubuntu 14.10
在终端中输入了:gcc -S -o main.s main.c -m32
接着打开main.s并通过gdb命令进行分析:
gdb ./main
gdb layout asm
gdb layout regs

然后得到如下结果:


所需要注意的是,如果gdb提示The program is not being run.则输入r。如果要结束调试则输入kill,退出输入q。
设置断点
(gdb)b main
(gdb)b a
(gdb)b b
接着:输入r运行。
然后输入:
(gdb)si
进行逐句分析。

结果发现一个有趣的现象便是:函数真正开始的地方为:<function name+3>的位置。

输入(gdb)layout regs查看寄存器的结果:
这里我选了几张,因为步骤太多了:
开始:
第一步:
最后:

第三章 分析
a:
pushl %ebp
esp先指向下一位,将esp和ebp指向同一地方。
movl %esp, %ebp
将esp和ebp指向同一地方。
movl 8(%ebp), %eax
将epb的值8赋值给eax。
addl $5, %eax
eax的值加5。
popl %ebp
相当于两步:
movl (%esp),%eax
addl $4,%esp
则:将esp所指向的值赋值给eax,接着esp向上移动一位。
ret
相当于pop eip(*)
则:eip的值赋值给eax,而esp则指向上一位内存空间。
b:
pushl %ebp
esp先指向下一位,将ebp的值赋值给esp所指的地方。
movl %esp, %ebp
将esp和ebp指向同一地方。
pushl 8(%ebp)
将8赋值给ebp所指向的地址空间。
call a
将eip的值记为下一条指令的地址,esp指向下一个地址空间。这时转向a函数。
addl $4, %esp
esp往上移一位4。
leave
esp和指向同一位置ebp。
然后将esp所指向的内存空间的值付给eax。
esp往上移一位。
ret
main:
pushl %ebp
相当于两步:
subl $4 %esp
movl %ebp,(%esp)
esp先指向下一位,将ebp的地址值赋值给esp所指的地方。
movl %esp, %ebp
将esp和ebp指向同一地方。
pushl $7
esp向下移一位,然后将7赋值给esp所指的地方。
call b
分为两步:
pushl %eip(*)
movl b的地址 %eip(*)
将eip的值记为下一条指令的地址,esp指向下一个地址空间。这时转向b函数。
addl $4, %esp(ubuntu多余代码,不予以分析)
addl $6, %eax
eax的值加6。
leave
esp和指向同一位置ebp。
然后将esp所指向的内存空间的值赋值给eax。
esp往上移一位。
第四章 总结
在生成代码的时候,我发现生成了很多多余代码。而现在我才发现,这些代码都是因为自己没有写对函数名造成的。由于我更改了老师的代码,却没有更改相应的函数名导致了错误。也算是给自己的教训。还有,我还发现了一段多余的代码:addl $4,%esp,不知道是什么原因。这个是为了什么设定的呢?希望大家来讨论一下。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值