質問編集履歴
5
コンパイル時のオプションを追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -122,7 +122,7 @@
|
|
122
122
|
|
123
123
|
(あっているかは置いといて)結論が出たので勉強の意味も込めて書いておきます。
|
124
124
|
|
125
|
-
Zuishin様やcateye様がアドバイスしてくださったように一つ目のコードのアセンブルソースを確認したところ、このようになっていました。
|
125
|
+
Zuishin様やcateye様がアドバイスしてくださったように一つ目のコードのアセンブルソースを確認(gcc -S -O0 -fno-asynchronous-unwind-tables <ソース名>)したところ、このようになっていました。
|
126
126
|
|
127
127
|
```Assembly
|
128
128
|
|
4
軽微な修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -216,7 +216,7 @@
|
|
216
216
|
|
217
217
|
```
|
218
218
|
|
219
|
-
また、Chironian様のご指摘のようにgccはスタックフレームの開始アドレスを16バイト単位に調整しているようです。上のアセンブリソースに`subq $16, %rsp`という命令があることからもそれが窺えますし、main関数内で宣言する変数をもっと増やしてみたら`subq $32, %rsp`と変化したことから間違いないかと思います。
|
219
|
+
また、Chironian様のご指摘のようにやはりgccはスタックフレームの開始アドレスを16バイト単位に調整しているようです。上のアセンブリソースに`subq $16, %rsp`という命令があることからもそれが窺えますし、main関数内で宣言する変数をもっと増やしてみたら`subq $32, %rsp`と変化したことから間違いないかと思います。
|
220
220
|
|
221
221
|
最終的に、スタックは恐らくこんな感じになっているのではないかと考えました。(なぜか1列のテーブルが作れなかったのでしかたなく2列にしています)
|
222
222
|
|
@@ -234,7 +234,7 @@
|
|
234
234
|
|
235
235
|
|func関数のベースポインタ(8バイト)||
|
236
236
|
|
237
|
-
|
|
237
|
+
|main関数への戻り番地(たぶん8バイト?)||
|
238
238
|
|
239
239
|
|パディング(16-12=4バイト)||
|
240
240
|
|
3
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -116,4 +116,136 @@
|
|
116
116
|
|
117
117
|
|
118
118
|
|
119
|
-
環境はWSL(ubuntu)、コンパイラはgcc8.3.0でオプションは特につけてないです。
|
119
|
+
環境はWindows10 home(64bit)のWSL(ubuntu)、コンパイラはgcc8.3.0でオプションは特につけてないです。
|
120
|
+
|
121
|
+
### 追記
|
122
|
+
|
123
|
+
(あっているかは置いといて)結論が出たので勉強の意味も込めて書いておきます。
|
124
|
+
|
125
|
+
Zuishin様やcateye様がアドバイスしてくださったように一つ目のコードのアセンブルソースを確認したところ、このようになっていました。
|
126
|
+
|
127
|
+
```Assembly
|
128
|
+
|
129
|
+
.file "1.c"
|
130
|
+
|
131
|
+
.text
|
132
|
+
|
133
|
+
.section .rodata
|
134
|
+
|
135
|
+
.LC0:
|
136
|
+
|
137
|
+
.string "%p,%p,%p\n"
|
138
|
+
|
139
|
+
.text
|
140
|
+
|
141
|
+
.globl func
|
142
|
+
|
143
|
+
.type func, @function
|
144
|
+
|
145
|
+
func:
|
146
|
+
|
147
|
+
pushq %rbp
|
148
|
+
|
149
|
+
movq %rsp, %rbp
|
150
|
+
|
151
|
+
subq $16, %rsp
|
152
|
+
|
153
|
+
leaq -12(%rbp), %rcx
|
154
|
+
|
155
|
+
leaq -8(%rbp), %rdx
|
156
|
+
|
157
|
+
leaq -4(%rbp), %rax
|
158
|
+
|
159
|
+
movq %rax, %rsi
|
160
|
+
|
161
|
+
movl $.LC0, %edi
|
162
|
+
|
163
|
+
movl $0, %eax
|
164
|
+
|
165
|
+
call printf
|
166
|
+
|
167
|
+
nop
|
168
|
+
|
169
|
+
leave
|
170
|
+
|
171
|
+
ret
|
172
|
+
|
173
|
+
.size func, .-func
|
174
|
+
|
175
|
+
.globl main
|
176
|
+
|
177
|
+
.type main, @function
|
178
|
+
|
179
|
+
main:
|
180
|
+
|
181
|
+
pushq %rbp
|
182
|
+
|
183
|
+
movq %rsp, %rbp
|
184
|
+
|
185
|
+
subq $16, %rsp
|
186
|
+
|
187
|
+
leaq -12(%rbp), %rcx
|
188
|
+
|
189
|
+
leaq -8(%rbp), %rdx
|
190
|
+
|
191
|
+
leaq -4(%rbp), %rax
|
192
|
+
|
193
|
+
movq %rax, %rsi
|
194
|
+
|
195
|
+
movl $.LC0, %edi
|
196
|
+
|
197
|
+
movl $0, %eax
|
198
|
+
|
199
|
+
call printf
|
200
|
+
|
201
|
+
movl $0, %eax
|
202
|
+
|
203
|
+
call func
|
204
|
+
|
205
|
+
movl $0, %eax
|
206
|
+
|
207
|
+
leave
|
208
|
+
|
209
|
+
ret
|
210
|
+
|
211
|
+
.size main, .-main
|
212
|
+
|
213
|
+
.ident "GCC: (GNU) 8.3.0"
|
214
|
+
|
215
|
+
.section .note.GNU-stack,"",@progbits
|
216
|
+
|
217
|
+
```
|
218
|
+
|
219
|
+
また、Chironian様のご指摘のようにgccはスタックフレームの開始アドレスを16バイト単位に調整しているようです。上のアセンブリソースに`subq $16, %rsp`という命令があることからもそれが窺えますし、main関数内で宣言する変数をもっと増やしてみたら`subq $32, %rsp`と変化したことから間違いないかと思います。
|
220
|
+
|
221
|
+
最終的に、スタックは恐らくこんな感じになっているのではないかと考えました。(なぜか1列のテーブルが作れなかったのでしかたなく2列にしています)
|
222
|
+
|
223
|
+
|||
|
224
|
+
|
225
|
+
|:---:|---|
|
226
|
+
|
227
|
+
|パディング(16-12=4バイト)||
|
228
|
+
|
229
|
+
|変数f(4バイト)||
|
230
|
+
|
231
|
+
|変数e(4バイト)||
|
232
|
+
|
233
|
+
|変数d(4バイト)||
|
234
|
+
|
235
|
+
|func関数のベースポインタ(8バイト)||
|
236
|
+
|
237
|
+
|func関数を呼び出した地点への戻り番地(たぶん8バイト?)||
|
238
|
+
|
239
|
+
|パディング(16-12=4バイト)||
|
240
|
+
|
241
|
+
|変数c(4バイト)||
|
242
|
+
|
243
|
+
|変数b(4バイト)||
|
244
|
+
|
245
|
+
|変数a(4バイト)||
|
246
|
+
|
247
|
+
|main関数のベースポインタ(8バイト)||
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
これが変数cと変数dの間の20バイトのギャップの正体ではないかなあと思いました。
|
2
行末に不要な空白が入っていたのが気持ち悪かったので修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -16,29 +16,29 @@
|
|
16
16
|
|
17
17
|
```C
|
18
18
|
|
19
|
-
#include<stdio.h>
|
19
|
+
#include<stdio.h>
|
20
20
|
|
21
|
-
int func()
|
21
|
+
int func()
|
22
22
|
|
23
|
-
{
|
23
|
+
{
|
24
24
|
|
25
|
-
int d,e,f;
|
25
|
+
int d,e,f;
|
26
26
|
|
27
27
|
printf("%p,%p,%p\n",&d,&e,&f);
|
28
28
|
|
29
|
-
}
|
29
|
+
}
|
30
30
|
|
31
|
-
int main()
|
31
|
+
int main()
|
32
32
|
|
33
|
-
{
|
33
|
+
{
|
34
34
|
|
35
|
-
int a,b,c;
|
35
|
+
int a,b,c;
|
36
36
|
|
37
37
|
printf("%p,%p,%p\n",&a,&b,&c);
|
38
38
|
|
39
|
-
func();
|
39
|
+
func();
|
40
40
|
|
41
|
-
}
|
41
|
+
}
|
42
42
|
|
43
43
|
```
|
44
44
|
|
@@ -54,33 +54,33 @@
|
|
54
54
|
|
55
55
|
```C
|
56
56
|
|
57
|
-
#include<stdio.h>
|
57
|
+
#include<stdio.h>
|
58
58
|
|
59
|
-
int *p1,*p2;
|
59
|
+
int *p1,*p2;
|
60
60
|
|
61
|
-
void func()
|
61
|
+
void func()
|
62
62
|
|
63
|
-
{
|
63
|
+
{
|
64
64
|
|
65
|
-
int d,e,f;p2=&d;
|
65
|
+
int d,e,f;p2=&d;
|
66
66
|
|
67
|
-
printf("%p,%p,%p\n",&d,&e,&f);
|
67
|
+
printf("%p,%p,%p\n",&d,&e,&f);
|
68
68
|
|
69
|
-
}
|
69
|
+
}
|
70
70
|
|
71
|
-
int main()
|
71
|
+
int main()
|
72
72
|
|
73
|
-
{
|
73
|
+
{
|
74
74
|
|
75
|
-
int a,b,c;p1=&c;
|
75
|
+
int a,b,c;p1=&c;
|
76
76
|
|
77
|
-
printf("%p,%p,%p\n",&a,&b,&c);
|
77
|
+
printf("%p,%p,%p\n",&a,&b,&c);
|
78
78
|
|
79
|
-
func();
|
79
|
+
func();
|
80
80
|
|
81
81
|
printf("%d\n",sizeof(int)*(p1-p2));
|
82
82
|
|
83
|
-
}
|
83
|
+
}
|
84
84
|
|
85
85
|
```
|
86
86
|
|
1
test
CHANGED
File without changes
|
test
CHANGED
@@ -113,3 +113,7 @@
|
|
113
113
|
|
114
114
|
|
115
115
|
int型は(私の環境だと)4バイトの大きさを持つので、スタック上で変数cの領域が終わってから変数dの領域が始まるまでに20バイトの空白?があるようです。これはどういった意味を持つのでしょうか?
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
環境はWSL(ubuntu)、コンパイラはgcc8.3.0でオプションは特につけてないです。
|