作者ucrxzero (RX-0)
看板C_and_CPP
標題[問題] stack裡變數位址越後定義越高
時間Fri Oct 23 01:00:27 2020
開發平台(Platform): (Ex: Win10, Linux, ...)
Linux
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
gcc
問題(Question):
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
int main(){
int a=1000;
int b=2000;
int c=3000;
int d=4000;
int e=5000;
int f=6000;
return 0;
}
產生以下組語
movl $1000, -24(%rbp)
movl $2000, -20(%rbp)
movl $3000, -16(%rbp)
movl $4000, -12(%rbp)
movl $5000, -8(%rbp)
movl $6000, -4(%rbp)
movl $0, %eax
popq
為什麼不是慢慢往下長而是先從最下面長上來?
這是照a~f的位址印的
0x7ffdb6a309a0
0x7ffdb6a309a4
0x7ffdb6a309a8
0x7ffdb6a309ac
0x7ffdb6a309b0
0x7ffdb6a309b4
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 43.248.19.192 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1603386030.A.275.html
1F:→ ucrxzero: 有組語版嗎? 10/23 01:54
2F:→ ucrxzero: 另外我想問為何eax會是0~ 10/23 01:55
※ 編輯: ucrxzero (43.248.19.192 臺灣), 10/23/2020 01:57:45
3F:→ firejox: 組語板 asm 10/23 02:11
4F:→ ucrxzero: 發在這也可以吧 10/23 02:12
5F:→ ucrxzero: 我要問位址的問題而已 10/23 02:12
6F:→ ucrxzero: 感謝提供 10/23 02:12
7F:→ ucrxzero: 想到台大電機這題剛好請神人解釋 10/23 02:19
9F:→ ucrxzero: 904.html 10/23 02:19
10F:推 KaryuuIssen: 順序是未定義的 怎麼長都可以 我記得緩衝區防護 10/23 03:22
11F:→ KaryuuIssen: 好像有影響 你編譯加個 -fno-stack-protector 試試 10/23 03:22
加了就往下長欸好神奇喔
12F:推 LPH66: 然後 %eax 設為 0 就是你的 return 0 10/23 04:22
13F:→ Lipraxde: 怎麼 return value 可以參考 System V ABI 裡的 Parame 10/23 06:58
14F:→ Lipraxde: ter Passing,不同的 return type 有不同的傳法,屬於 10/23 06:58
15F:→ Lipraxde: integer 的是用 rax、rdx return 10/23 06:58
※ 編輯: ucrxzero (43.248.19.192 臺灣), 10/23/2020 09:15:28
16F:→ ucrxzero: 感謝大大 10/23 09:26
17F:→ ucrxzero: 所以結論是往上往下都可 heap是只能往上 10/23 09:45
18F:→ ucrxzero: 回傳值是給eax用的這樣嗎 10/23 09:45
19F:→ ucrxzero: 不過直觀感覺往上長才會溢位需要保護 反而要保護往下長 10/23 09:46
20F:→ ucrxzero: 我看來要多看書 10/23 09:47
21F:→ Lipraxde: 應該是要看進出 function 時 stack pointer 的變化,st 10/23 11:49
22F:→ Lipraxde: ack 應該還是往下長的 10/23 11:49
23F:→ ucrxzero: CSAPP上說return address是%rbp+4原來是eax 10/23 11:54
24F:→ ucrxzero: 感謝大大 10/23 11:54
25F:推 LPH66: 呃, 不對; eax 和 return address 是不同的東西 10/23 14:06
26F:→ LPH66: eax 是回傳的值, return address 是回去的程式位址 10/23 14:07
27F:→ LPH66: 硬要說的話後者是 return 0 的 return, 前者是 0 10/23 14:07
28F:→ ucrxzero: 這篇真多寶藏 10/23 19:40
29F:推 b0920075: 往上往下通常用在記憶體空間的擴增方向不太會用在區域 10/23 21:50
30F:→ b0920075: 變數的賦值順序... 10/23 21:50
31F:→ ucrxzero: 我想也是 10/23 23:27
32F:→ ucrxzero: heap 是用best fit 用過的可能還會釋放或GC後重新分配 10/23 23:28
33F:→ ucrxzero: 不一定只會往上 10/23 23:28
34F:→ sarafciel: 你看movl塞的offset都是負的 所以stack是往低位長 10/24 21:06
35F:→ sarafciel: 至於stack frame裡面要怎麼塞區域變數就是看編譯器高興 10/24 21:08
36F:→ ucrxzero: 我看這兩天把CSAPP的procedure call看完 10/25 02:53
37F:推 Killercat: 雖然說這個並沒有定義,但是大多數作業系統實作上是一 10/27 15:05
38F:→ Killercat: 多半使用類似的做法,可以參考這個網址 10/27 15:06
40F:→ Killercat: Linux來講直到2.16都是這樣,所以stack/heap喜相逢會 10/27 15:06
41F:→ Killercat: 碰到一些問題,不過後來有稍微做了些改變 10/27 15:06
42F:→ Killercat: 不過雖然stack是往下長,但是是先切出一塊指定大小空間 10/27 15:08
43F:→ Killercat: 再把指標訂到底部,所以pointer的operation++還是可以 10/27 15:08
44F:→ Killercat: 正常的做iteration,這是後話... 10/27 15:08
45F:→ ucrxzero: 樓上強強強 10/29 00:26
46F:→ ucrxzero: 不過stack跟heap中間應該還有共享庫段才對? 10/29 03:29
47F:→ Killercat: er...不是強,我想這邊大多數人應該認為這個模型是常識 10/29 14:37
48F:→ Killercat: 所以沒有特別提出來而已.... 10/29 14:37
49F:→ Killercat: 只是我突然發現這個模型似乎就是你卡住的點 10/29 14:38
50F:→ ucrxzero: 可是那題台大電機我看大家都沒有講對說 10/29 14:55
51F:→ ucrxzero: 才想說順便來發文 10/29 14:55
52F:→ Lipraxde: 沒人講對?我看那篇 47 樓的 b 大明明寫了「stack是往 10/29 18:12
53F:→ Lipraxde: 下長,但local變數擺放順序C語言規格書沒有強制規定」 10/29 18:12
54F:→ ucrxzero: 喔我演殘 10/29 18:43
55F:→ ucrxzero: *眼 10/29 18:43
56F:→ ucrxzero: 補充一下因為我翻CSAPP的時候他直接這樣舉例我才誤會 10/30 18:29
57F:→ ucrxzero: 有兩點 這本不是新手看 或是我太爛 10/30 18:29
CSAPP 3.12 完美解決這個疑問了QQ
※ 編輯: ucrxzero (43.248.19.192 臺灣), 10/31/2020 23:46:10