- 论坛徽章:
- 0
|
我们先看看一个小程序,再看看它对应的汇编代码,一切都清楚了。
#include
int main(int argc, char* argv[])
{
int n = 0;
int* p = alloca(1024);
printf("&n=%p p=%p\n", &n, p);
return 0;
}
汇编代码为:
int main(int argc, char* argv[])
{
8048394: 55 push %ebp
8048395: 89 e5 mov %esp,%ebp
8048397: 83 ec 18 sub $0x18,%esp
804839a: 83 e4 f0 and $0xfffffff0,%esp
804839d: b8 00 00 00 00 mov $0x0,%eax
80483a2: 83 c0 0f add $0xf,%eax
80483a5: 83 c0 0f add $0xf,%eax
80483a8: c1 e8 04 shr $0x4,%eax
80483ab: c1 e0 04 shl $0x4,%eax
80483ae: 29 c4 sub %eax,%esp
int n = 0;
80483b0: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp)
int* p = alloca(1024);
80483b7: 81 ec 10 04 00 00 sub $0x410,%esp
80483bd: 8d 44 24 0c lea 0xc(%esp),%eax
80483c1: 83 c0 0f add $0xf,%eax
80483c4: c1 e8 04 shr $0x4,%eax
80483c7: c1 e0 04 shl $0x4,%eax
80483ca: 89 45 f8 mov %eax,0xfffffff8(%ebp)
printf("&n=%p p=%p\n", &n, p);
80483cd: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
80483d0: 89 44 24 08 mov %eax,0x8(%esp)
80483d4: 8d 45 fc lea 0xfffffffc(%ebp),%eax
80483d7: 89 44 24 04 mov %eax,0x4(%esp)
80483db: c7 04 24 98 84 04 08 movl $0x8048498,(%esp)
80483e2: e8 d1 fe ff ff call 80482b8
return 0;
80483e7: b8 00 00 00 00 mov $0x0,%eax
}
其中关键的一条指令为:sub $0x410,%esp
由此可以看出实现alloca,仅仅是把ESP减去指定大小,扩大栈空间(记记住栈是向下增长),这块空间就是分配的内存。
3. 可变参数的实现。
对新手来说,可变参数的函数也是比较神奇。还是以一个小程序来说明它的实现。
#include
#include
int print(const char* fmt, ...)
{
int n1 = 0;
int n2 = 0;
int n3 = 0;
va_list ap;
va_start(ap, fmt);
n1 = va_arg(ap, int);
n2 = va_arg(ap, int);
n3 = va_arg(ap, int);
va_end(ap);
printf("n1=%d n2=%d n3=%d\n", n1, n2, n3);
return 0;
}
int main(int arg, char argv[])
{
print("%d\n", 1, 2, 3);
return 0;
}
我们看看对应的汇编代码:
int print(const char* fmt, ...)
{
8048394: 55 push %ebp
8048395: 89 e5 mov %esp,%ebp
8048397: 83 ec 28 sub $0x28,%esp
int n1 = 0;
804839a: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp)
int n2 = 0;
80483a1: c7 45 f8 00 00 00 00 movl $0x0,0xfffffff8(%ebp)
int n3 = 0;
80483a8: c7 45 f4 00 00 00 00 movl $0x0,0xfffffff4(%ebp)
va_list ap;
va_start(ap, fmt);
80483af: 8d 45 0c lea 0xc(%ebp),%eax
80483b2: 89 45 f0 mov %eax,0xfffffff0(%ebp)
n1 = va_arg(ap, int);
80483b5: 8b 55 f0 mov 0xfffffff0(%ebp),%edx
80483b8: 8d 45 f0 lea 0xfffffff0(%ebp),%eax
80483bb: 83 00 04 addl $0x4,(%eax)
80483be: 8b 02 mov (%edx),%eax
80483c0: 89 45 fc mov %eax,0xfffffffc(%ebp)
n2 = va_arg(ap, int);
80483c3: 8b 55 f0 mov 0xfffffff0(%ebp),%edx
80483c6: 8d 45 f0 lea 0xfffffff0(%ebp),%eax
80483c9: 83 00 04 addl $0x4,(%eax)
80483cc: 8b 02 mov (%edx),%eax
80483ce: 89 45 f8 mov %eax,0xfffffff8(%ebp)
n3 = va_arg(ap, int);
80483d1: 8b 55 f0 mov 0xfffffff0(%ebp),%edx
80483d4: 8d 45 f0 lea 0xfffffff0(%ebp),%eax
80483d7: 83 00 04 addl $0x4,(%eax)
80483da: 8b 02 mov (%edx),%eax
80483dc: 89 45 f4 mov %eax,0xfffffff4(%ebp)
va_end(ap);
printf("n1=%d n2=%d n3=%d\n", n1, n2, n3);
80483df: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
80483e2: 89 44 24 0c mov %eax,0xc(%esp)
80483e6: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
80483e9: 89 44 24 08 mov %eax,0x8(%esp)
80483ed: 8b 45 fc mov 0xfffffffc(%ebp),%eax
80483f0: 89 44 24 04 mov %eax,0x4(%esp)
80483f4: c7 04 24 f8 84 04 08 movl $0x80484f8,(%esp)
80483fb: e8 b8 fe ff ff call 80482b8
return 0;
8048400: b8 00 00 00 00 mov $0x0,%eax
}
int main(int arg, char argv[])
{
8048407: 55 push %ebp
8048408: 89 e5 mov %esp,%ebp
804840a: 83 ec 18 sub $0x18,%esp
804840d: 83 e4 f0 and $0xfffffff0,%esp
8048410: b8 00 00 00 00 mov $0x0,%eax
8048415: 83 c0 0f add $0xf,%eax
8048418: 83 c0 0f add $0xf,%eax
804841b: c1 e8 04 shr $0x4,%eax
804841e: c1 e0 04 shl $0x4,%eax
8048421: 29 c4 sub %eax,%esp
int n = print("%d\n", 1, 2, 3);
8048423: c7 44 24 0c 03 00 00 movl $0x3,0xc(%esp)
804842a: 00
804842b: c7 44 24 08 02 00 00 movl $0x2,0x8(%esp)
8048432: 00
8048433: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp)
804843a: 00
804843b: c7 04 24 0b 85 04 08 movl $0x804850b,(%esp)
8048442: e8 4d ff ff ff call 8048394
8048447: 89 45 fc mov %eax,0xfffffffc(%ebp)
return 0;
804844a: b8 00 00 00 00 mov $0x0,%eax
}
从汇编代码中,我们可以看出,参数是逆序入栈的。在取参数时,先让ap指向第一个参数,又因为栈是向下增长的,不断把指针向上移动就可以取出所有参数了。
l 堆
在内存分配算法一节中再详细讲解。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/30686/showart_247775.html |
|