访问栈上的数组和堆中的数组的区别



先看一段简单的代码

void test()
{
  int a[10] = {0};
  int* b = malloc(10 * sizeof(int));
   a[0] = 0;
   b[0] = 0;
}


将以上代码保存成test.c,用gcc -c test.c生成目标代码,用objdump -o 反编译,得到以下汇编

   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	57                   	push   %edi
   4:	53                   	push   %ebx
   5:	83 ec 40             	sub    $0x40,%esp
   8:	8d 5d d0             	lea    -0x30(%ebp),%ebx
   b:	b8 00 00 00 00       	mov    $0x0,%eax
  10:	ba 0a 00 00 00       	mov    $0xa,%edx
  15:	89 df                	mov    %ebx,%edi
  17:	89 d1                	mov    %edx,%ecx
  19:	f3 ab                	rep stos %eax,%es:(%edi)
  1b:	c7 04 24 28 00 00 00 	movl   $0x28,(%esp)
  22:	e8 fc ff ff ff       	call   23 <test+0x23>
  27:	89 45 cc             	mov    %eax,-0x34(%ebp)   
  2a:	c7 45 d0 00 00 00 00 	movl   $0x0,-0x30(%ebp)  -->a[0] = 0;
  31:	8b 45 cc             	mov    -0x34(%ebp),%eax  -->b存储着malloc返回的地址,此地址存放在-0x34(%ebp)中,此句把b所指的地址赋给%eax
  34:	c7 00 00 00 00 00    	movl   $0x0,(%eax)       -->b[0] = 0;寄存器间接寻址
  3a:	83 c4 40             	add    $0x40,%esp
  3d:	5b                   	pop    %ebx
  3e:	5f                   	pop    %edi
  3f:	5d                   	pop    %ebp
  40:	c3                   	ret    


所以a[0] = 0;只需要一句指令,因为数组a的全部成员都在栈上;

而b[0] = 0需要两条指令,因为数组b的地址存放在栈上,而数组的实际内容在堆中,需要通过栈上的地址间接寻址


展开阅读全文

没有更多推荐了,返回首页