关于函数调用时参数和局部变量的问题

wlzx5857491 2014-08-02 02:10:41
最近看了很多关于函数调用过程中参数和局部变量在栈中分配和释放 方面的资料,有一些领悟,但也有一些不解,
1 push ebp
2 mov ebp,esp
3 sub esp,40h
4 push ebx
5 push esi
6 push edi
7 lea edi,[ebp-40h]
8 mov ecx,10h
9 mov eax,0CCCCCCCCh
10 rep stos dword ptr [edi]

这是在windows下查看一个c函数得到的汇编代码,10行之后的没有贴了

1
我把同样的c函数拿到linux(乌班图)下,发现3-10行都没有,而且在windows下最后都有如下代码,
pop edi
pop esi
pop ebx
除了edi我看到有时存一下地址,没看到使用esi,ebx,每次都是函数压栈了,结束前出栈了,那ebx,esi有什么用呢?linux为什么没有这么做呢?

2
8-10行把局部变量占的内存的字节全部设置成了cc,查了下说是什么int3中断,int3中断是干什么的,linux下没有这样做,那linux下没有这种中断还是?

3
4 int foo(int a,int b)
5 {
6 unsigned int m=5;
7 unsigned int p=10;
8 /* printf("%p\n",&a);
9 printf("%p\n",&b);
10 printf("%p\n",&m);
11 printf("%p\n",&p);*/
12 return a+b;
13 }

9 push ebp
10 .cfi_def_cfa_offset 8
11 .cfi_offset 5, -8
12 mov ebp, esp
13 .cfi_def_cfa_register 5
14 sub esp, 16
15 mov DWORD PTR [ebp-8], 5
16 mov DWORD PTR [ebp-4], 10
17 mov eax, DWORD PTR [ebp+12]
18 mov edx, DWORD PTR [ebp+8]
19 add eax, edx
20 leave

最让我不解的是上面的程序,看了很多资料,这时栈布局大概是这样:
int b
int a
eip
ebp <- ebp指向这
int p
int m
(我试验了下,发现windows下局部变量是先声明的在高地址,而乌班图里先声明的在底地址)

ebp-4 是第一个局部变量,ebp+8是第一个参数,但是我打印地址
a 0xbf8da320
b 0xbf8da324
m 0xbf8da308
p 0xbf8da30c

离得最近的是p和a,相差0x14,也就是20字节,但是汇编里不是8+4=12字节吗,为什么会这样?

说了很多,忘各位不吝赐教,谢了

...全文
378 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
大熊猫侯佩 2014-09-01
  • 打赏
  • 举报
回复
编译器不一样吧?你在windows下也是用gcc编的吗?
WJN92 2014-08-06
  • 打赏
  • 举报
回复
不同的编译器的约定不同啦
赵4老师 2014-08-05
  • 打赏
  • 举报
回复
修改编译选项
zara 2014-08-04
  • 打赏
  • 举报
回复
不了解 linux/ubutun 的机制,说下 windows 环境下的自己的理解吧。
1. 那是个寄存器是保存和恢复,是基于函数/子程对寄存器的使用约定来的,这个约定是说,子程或函数可以随意使用 eax/edx/ecx 这三个寄存器,而 ebx/esi/edi 如果使用了则需要进行恢复的操作;这样的约定意味着,调用子程或函数前后,ecx/edx 是可能会被改写的,eax 嘛通常作为结果返回自不待言;而 ebx/esi/edi 则无须担心。
2. 这个应该是 c 编译器的简单的溢出异常的检测措施吧,具体做法和编译时的选项有关。
3. 相差 20 ,是由于在参数和局部变量之间,还有函数的返回地址以及刚入函数时对 ebp 的压栈保存。

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧