test environment: 32bit code, in bootloader
array 和 pointer 有什麼不同呢?C 专家编程 (Expert C Programming) 裡頭有不少的說明。我要提到的是另外一個觀察。
我透過作業系統之前的程式 (這樣可以簡化), 使用 bochs 內建除錯器 single step 跑了一次, 終於有了深刻的印象。
下圖是我將記憶體的內容 (stack) 根據程式畫出來, 對照著反組譯的 code, 應該很好理解。
17 7c21: 67 66 8d 45 f2 lea -0xe(%ebp),%eax
把 -0xe(%ebp) 的位址 (ffc4) 抓出來。
arr 本身就代表某個位址, 就是 ffc4, 而在 c 語言用 &arr, arr 都是得到 ffc4。
arrp 本身代表某個位址 (ffce), 而這個位址用來存一個位址 0000ffc4。 &arrp 得到 ffce, arrp 則是 ffc4, 那 *arrp 呢?自然就是從 ffc4 抓一個 byte 的值, 就是 0x61 = 'a'。
%epb = 0xffd2 這是系統的 epb 值, 在不同平台上有可能會不同。
| ffd2 |
00 | |
00 | |
ff | |
c4 | ffce -4(%ebp) arrp |
00 | |
69 | ffcc -6(%ebp) |
68 | |
67 | |
66 | |
65 | ffc8 -a(%epb) |
64 | |
63 | |
62 | |
61 | ffc4 -e(%epb) arr |
|
這個簡單的組合語言程式可花了我不少腦力 |
這是另外一個有趣的問題 (
作者: sunlights (sunlights) 看板: C_and_CPP標題: [問題] 指標和陣列的問題)
12 int addr = &arr+1;
會怎樣?
組合語言面前沒有秘密, 似乎就是這行:
20 7c30: 66 83 c0 0a add $0xa,%eax
我沒有答案, 為什麼該 C 語言 +1 的動作在組合語言變成 + 0xa, 不懂?
若是改為
&arr+2;
&arr+3;
add $0x14,%eax
add $0x1e,%eax
每加 1, 組合語言則是 + 0xa
難道這是未定義之行為嗎?
推 LPH66:你的 &arr 其型態是 char (*)[10] 因此 +1 時會跳十格 10/05 09:52
→ LPH66:之所以是十格是因為 sizeof(char[10]) == 10 的關係 10/05 09:52
感謝 LPH66, 一語驚醒夢中人。
arr+1
&arr+1
行為很不同, 注意別寫錯了。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。