作者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/cn.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