訪問棧上的陣列和堆中的陣列的區別
阿新 • • 發佈:2019-02-05
先看一段簡單的程式碼
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的地址存放在棧上,而陣列的實際內容在堆中,需要通過棧上的地址間接定址