1. 程式人生 > >訪問棧上的陣列和堆中的陣列的區別

訪問棧上的陣列和堆中的陣列的區別



先看一段簡單的程式碼

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的地址存放在棧上,而陣列的實際內容在堆中,需要通過棧上的地址間接定址