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

关于函数调用时参数和局部变量的问题
最近看了很多关于函数调用过程中参数和局部变量在栈中分配和释放 方面的资料,有一些领悟,但也有一些不解,
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字节吗,为什么会这样?

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


------解决思路----------------------
不了解 linux/ubutun 的机制,说下 windows 环境下的自己的理解吧。
1. 那是个寄存器是保存和恢复,是基于函数/子程对寄存器的使用约定来的,这个约定是说,子程或函数可以随意使用 eax/edx/ecx 这三个寄存器,而 ebx/esi/edi 如果使用了则需要进行恢复的操作;这样的约定意味着,调用子程或函数前后,ecx/edx 是可能会被改写的,eax 嘛通常作为结果返回自不待言;而 ebx/esi/edi 则无须担心。
2. 这个应该是 c 编译器的简单的溢出异常的检测措施吧,具体做法和编译时的选项有关。
3. 相差 20 ,是由于在参数和局部变量之间,还有函数的返回地址以及刚入函数时对 ebp 的压栈保存。