Mercurial > pub > dyncall > dyncall
annotate doc/disas_examples/x86.fastcall_gnu.disas @ 497:cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
author | Tassilo Philipp |
---|---|
date | Wed, 23 Mar 2022 15:24:31 +0100 |
parents | 79e76734bb5c |
children | fc614cb865c6 |
rev | line source |
---|---|
470 | 1 ; #include <stdlib.h> |
2 ; | |
3 ; void __attribute__((fastcall)) leaf_call(int b, int c, int d, int e, int f, int g, int h) | |
4 ; { | |
5 ; } | |
6 ; | |
7 ; void __attribute__((fastcall)) nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h) | |
8 ; { | |
9 ; /* use some local data */ | |
10 ; *(char*)alloca(220) = 'L'; | |
11 ; leaf_call(b, c, d, e, f, g, h); | |
12 ; } | |
13 ; | |
14 ; int main() | |
15 ; { | |
16 ; nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7); | |
17 ; return 0; | |
18 ; } | |
19 | |
20 | |
21 | |
22 ; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 (w/ flags to simplify: -fno-stack-protector -fno-pic) | |
23 | |
24 00001205 <leaf_call>: | |
25 1205: 55 push %ebp ; | | |
26 1206: 89 e5 mov %esp,%ebp ; | prolog | |
27 1208: 83 ec 08 sub $0x8,%esp ; | | |
28 120b: 89 4d fc mov %ecx,-0x4(%ebp) ; | |
29 120e: 89 55 f8 mov %edx,-0x8(%ebp) ; | |
30 1211: 90 nop ; | |
31 1212: c9 leave ; | | |
32 1213: c2 14 00 ret $0x14 ; | epilog | |
33 | |
34 00001216 <nonleaf_call>: | |
35 1216: 55 push %ebp ; | | |
36 1217: 89 e5 mov %esp,%ebp ; | prolog | |
37 1219: 83 ec 18 sub $0x18,%esp ; / | |
38 121c: 89 4d f4 mov %ecx,-0xc(%ebp) ; in arg 0 -> local area on stack | |
39 121f: 89 55 f0 mov %edx,-0x10(%ebp) ; in arg 1 -> local area on stack | |
40 1222: b8 10 00 00 00 mov $0x10,%eax ; | | |
41 1227: 83 e8 01 sub $0x1,%eax ; | | |
42 122a: 05 e8 00 00 00 add $0xe8,%eax ; | | |
43 122f: b9 10 00 00 00 mov $0x10,%ecx ; | alloca (seems like 220 is rounded up for stack alignment purposes) | |
44 1234: ba 00 00 00 00 mov $0x0,%edx ; | | |
45 1239: f7 f1 div %ecx ; | | |
46 123b: 6b c0 10 imul $0x10,%eax,%eax ; | | |
47 123e: 29 c4 sub %eax,%esp ; / | |
48 1240: 89 e0 mov %esp,%eax ; \ | |
49 1242: 83 c0 0f add $0xf,%eax ; | | |
50 1245: c1 e8 04 shr $0x4,%eax ; | align alloca'd space | |
51 1248: c1 e0 04 shl $0x4,%eax ; | | |
52 124b: c6 00 4c movb $0x4c,(%eax) ; write 'L' to alloca'd space | |
53 124e: 8b 45 f0 mov -0x10(%ebp),%eax ; in arg 1 (from local area) -> eax (then copied to ecx/arg0, below, could be done directly) | |
54 1251: 83 ec 0c sub $0xc,%esp ; @@@ unsure why, alignment? | |
55 1254: ff 75 1c pushl 0x1c(%ebp) ; | | |
56 1257: ff 75 18 pushl 0x18(%ebp) ; | | |
57 125a: ff 75 14 pushl 0x14(%ebp) ; | read in args 3-7 from prev frame's param area, and ... | |
58 125d: ff 75 10 pushl 0x10(%ebp) ; | ... push onto stack as arg 2-6 | |
59 1260: ff 75 0c pushl 0xc(%ebp) ; | | |
60 1263: 8b 55 08 mov 0x8(%ebp),%edx ; arg 1 (via reg, read in arg 2 from prev frame's param area) | |
61 1266: 89 c1 mov %eax,%ecx ; arg 0 (via reg) | |
62 1268: e8 98 ff ff ff call 1205 <leaf_call> ; push return address and call | |
63 126d: 83 c4 0c add $0xc,%esp ; @@@ restore esp to what it was before pushing args | |
64 1270: 90 nop ; | |
65 1271: c9 leave ; | | |
66 1272: c2 18 00 ret $0x18 ; | epilog | |
67 | |
68 00001275 <main>: | |
69 1275: 8d 4c 24 04 lea 0x4(%esp),%ecx ; | | |
70 1279: 83 e4 f0 and $0xfffffff0,%esp ; | @@@? alignment? | |
71 127c: ff 71 fc pushl -0x4(%ecx) ; | prolog | |
72 127f: 55 push %ebp ; | | |
73 1280: 89 e5 mov %esp,%ebp ; | | |
74 1282: 51 push %ecx ; preserve ecx (so it can be used for passing arg 0) | |
75 1283: 83 ec 04 sub $0x4,%esp ; @@@ unsure why, alignment? | |
76 1286: 83 ec 08 sub $0x8,%esp ; @@@ unsure why, alignment? pointless | |
77 1289: 6a 07 push $0x7 ; arg 7 | |
78 128b: 6a 06 push $0x6 ; arg 6 | |
79 128d: 6a 05 push $0x5 ; arg 5 | |
80 128f: 6a 04 push $0x4 ; arg 4 | |
81 1291: 6a 03 push $0x3 ; arg 3 | |
82 1293: 6a 02 push $0x2 ; arg 2 | |
83 1295: ba 01 00 00 00 mov $0x1,%edx ; arg 1 (via reg) | |
84 129a: b9 00 00 00 00 mov $0x0,%ecx ; arg 0 (via reg) | |
85 129f: e8 72 ff ff ff call 1216 <nonleaf_call> ; push return address and call | |
86 12a4: 83 c4 08 add $0x8,%esp ; @@@ restore one of the two "sub...esp"s above | |
87 12a7: b8 00 00 00 00 mov $0x0,%eax ; return value | |
88 12ac: 8b 4d fc mov -0x4(%ebp),%ecx ; restore ecx | |
89 12af: c9 leave ; | | |
90 12b0: 8d 61 fc lea -0x4(%ecx),%esp ; | epilog | |
91 12b3: c3 ret ; | | |
92 | |
93 | |
94 | |
95 ; ---------- vararg call (shows that all args are pushed) ----------> | |
96 | |
97 ; void __attribute__((fastcall)) leaf_call(int a, short b, char c, ...) | |
98 ; { | |
99 ; } | |
100 ; | |
101 ; int main() | |
102 ; { | |
103 ; leaf_call(0, 1, 2, 3, 4, 5, 6, 7LL); | |
104 ; return 0; | |
105 ; } | |
106 | |
107 | |
108 | |
109 ; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 (w/ flags to simplify: -fno-stack-protector -fno-pic) | |
110 | |
111 00001205 <leaf_call>: | |
112 1205: 55 push %ebp | |
113 1206: 89 e5 mov %esp,%ebp | |
114 1208: 90 nop | |
115 1209: 5d pop %ebp | |
116 120a: c3 ret | |
117 | |
118 0000120b <main>: | |
119 120b: 55 push %ebp | |
120 120c: 89 e5 mov %esp,%ebp | |
121 120e: 6a 00 push $0x0 | |
122 1210: 6a 07 push $0x7 | |
123 1212: 6a 06 push $0x6 | |
124 1214: 6a 05 push $0x5 | |
125 1216: 6a 04 push $0x4 | |
126 1218: 6a 03 push $0x3 | |
127 121a: 6a 02 push $0x2 | |
128 121c: 6a 01 push $0x1 | |
129 121e: 6a 00 push $0x0 | |
130 1220: e8 e0 ff ff ff call 1205 <leaf_call> | |
131 1225: 83 c4 24 add $0x24,%esp | |
132 1228: b8 00 00 00 00 mov $0x0,%eax | |
133 122d: c9 leave | |
134 122e: c3 ret | |
135 | |
136 | |
137 | |
138 ; ---------- structs by value (arg and return value), struct arg not fitting in regs ----------> | |
139 | |
140 ; struct A { int x; short y; char z; long long t; }; | |
141 ; | |
142 ; struct A __attribute__((fastcall)) leaf_call(struct A a, short b, long long c, char d, int e, int f, int g, long long h) | |
143 ; { | |
144 ; a.x += 1; | |
145 ; return a; | |
146 ; } | |
147 ; | |
148 ; int main() | |
149 ; { | |
150 ; struct A a ={9, 99, 23, 12LL}; | |
151 ; leaf_call(a, 1, 2, 3, 4, 5, 6, 7LL); | |
152 ; return 0; | |
153 ; } | |
154 | |
155 | |
156 | |
157 ; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 (w/ flags to simplify: -fno-stack-protector -fno-pic) | |
158 | |
159 00001205 <leaf_call>: | |
160 1205: 55 push %ebp ; | | |
161 1206: 89 e5 mov %esp,%ebp ; | prolog | |
162 1208: 83 ec 20 sub $0x20,%esp ; | | |
163 120b: 89 4d fc mov %ecx,-0x4(%ebp) ; ptr to retval space for struct (hidden first arg) -> local area | |
164 120e: 8b 45 18 mov 0x18(%ebp),%eax ; | |
165 1211: 8b 55 24 mov 0x24(%ebp),%edx ; | |
166 1214: 66 89 45 f8 mov %ax,-0x8(%ebp) ; | |
167 1218: 8b 45 1c mov 0x1c(%ebp),%eax ; | |
168 121b: 89 45 f0 mov %eax,-0x10(%ebp) ; | |
169 121e: 8b 45 20 mov 0x20(%ebp),%eax ; | |
170 1221: 89 45 f4 mov %eax,-0xc(%ebp) ; | |
171 1224: 89 d0 mov %edx,%eax ; | |
172 1226: 88 45 ec mov %al,-0x14(%ebp) ; | |
173 1229: 8b 45 34 mov 0x34(%ebp),%eax ; | |
174 122c: 89 45 e0 mov %eax,-0x20(%ebp) ; | |
175 122f: 8b 45 38 mov 0x38(%ebp),%eax ; | |
176 1232: 89 45 e4 mov %eax,-0x1c(%ebp) ; | |
177 1235: 8b 45 08 mov 0x8(%ebp),%eax ; | | |
178 1238: 83 c0 01 add $0x1,%eax ; | a.x += 1 (written to param area of prev frame) | |
179 123b: 89 45 08 mov %eax,0x8(%ebp) ; / | |
180 123e: 8b 45 fc mov -0x4(%ebp),%eax ; \ ptr to retval space | |
181 1241: 8b 55 08 mov 0x8(%ebp),%edx ; | | |
182 1244: 89 10 mov %edx,(%eax) ; | | |
183 1246: 8b 55 0c mov 0xc(%ebp),%edx ; | | |
184 1249: 89 50 04 mov %edx,0x4(%eax) ; | copy struct from param area in prev frame to retval space | |
185 124c: 8b 55 10 mov 0x10(%ebp),%edx ; | | |
186 124f: 89 50 08 mov %edx,0x8(%eax) ; | | |
187 1252: 8b 55 14 mov 0x14(%ebp),%edx ; | | |
188 1255: 89 50 0c mov %edx,0xc(%eax) ; | | |
189 1258: 8b 45 fc mov -0x4(%ebp),%eax ; return value (passed-in hidden ptr) | |
190 125b: c9 leave ; | | |
191 125c: c2 34 00 ret $0x34 ; | epilog | |
192 | |
193 0000125f <main>: | |
194 125f: 8d 4c 24 04 lea 0x4(%esp),%ecx ; | | |
195 1263: 83 e4 f0 and $0xfffffff0,%esp ; | | |
196 1266: ff 71 fc pushl -0x4(%ecx) ; | prolog | |
197 1269: 55 push %ebp ; | | |
198 126a: 89 e5 mov %esp,%ebp ; | | |
199 126c: 51 push %ecx ; preserve ecx (so it can be used for passing arg 0) | |
200 126d: 83 ec 24 sub $0x24,%esp ; reserve stack space for struct (local area) | |
201 1270: c7 45 e8 09 00 00 00 movl $0x9,-0x18(%ebp) ; | int x | |
202 1277: 66 c7 45 ec 63 00 movw $0x63,-0x14(%ebp) ; | short y | |
203 127d: c6 45 ee 17 movb $0x17,-0x12(%ebp) ; | struct values (local area) char z | |
204 1281: c7 45 f0 0c 00 00 00 movl $0xc,-0x10(%ebp) ; | | | |
205 1288: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) ; | | long long t | |
206 128f: 8d 45 d8 lea -0x28(%ebp),%eax ; ptr to space used for struct retval (passed as hidden first arg) -> eax | |
207 1292: 83 ec 04 sub $0x4,%esp ; @@@ unsure why, alignment? (also needed so what's in eax doesn't point below esp) | |
208 1295: 6a 00 push $0x0 ; | | |
209 1297: 6a 07 push $0x7 ; | arg 7 | |
210 1299: 6a 06 push $0x6 ; arg 6 | |
211 129b: 6a 05 push $0x5 ; arg 5 | |
212 129d: 6a 04 push $0x4 ; arg 4 | |
213 129f: 6a 03 push $0x3 ; arg 3 | |
214 12a1: 6a 00 push $0x0 ; | | |
215 12a3: 6a 02 push $0x2 ; | arg 2 (via stack b/c not first arg and > 32 bits) | |
216 12a5: 6a 01 push $0x1 ; arg 1 | |
217 12a7: ff 75 f4 pushl -0xc(%ebp) ; | | |
218 12aa: ff 75 f0 pushl -0x10(%ebp) ; | arg 0 (struct by value, pushed onto stack) | |
219 12ad: ff 75 ec pushl -0x14(%ebp) ; | | |
220 12b0: ff 75 e8 pushl -0x18(%ebp) ; | | |
221 12b3: 89 c1 mov %eax,%ecx ; ptr to free space for call's retval (struct), hidden first arg | |
222 12b5: e8 4b ff ff ff call 1205 <leaf_call> ; push return address and call | |
223 12ba: 83 c4 04 add $0x4,%esp ; @@@ restore esp to what it was before pushing args | |
224 12bd: b8 00 00 00 00 mov $0x0,%eax ; return value | |
225 12c2: 8b 4d fc mov -0x4(%ebp),%ecx ; restore ecx | |
226 12c5: c9 leave ; | | |
227 12c6: 8d 61 fc lea -0x4(%ecx),%esp ; | epilog | |
228 12c9: c3 ret ; | | |
229 | |
230 | |
231 | |
232 ; ---------- small struct returned by value (shows it's never returned via regs) ----------> | |
233 | |
234 ; struct A { short x; short y; }; | |
235 ; | |
236 ; struct A __attribute__((fastcall)) leaf_call(int a, int b) | |
237 ; { | |
238 ; struct A r = { 13, 15 }; | |
239 ; return r; | |
240 ; } | |
241 ; | |
242 ; int main() | |
243 ; { | |
244 ; leaf_call(99, 2); | |
245 ; return 0; | |
246 ; } | |
247 | |
248 | |
249 | |
250 ; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 (w/ flags to simplify: -fno-stack-protector -fno-pic) | |
251 | |
252 00001205 <leaf_call>: | |
253 1205: 55 push %ebp ; | | |
254 1206: 89 e5 mov %esp,%ebp ; | prolog | |
255 1208: 83 ec 18 sub $0x18,%esp ; | | |
256 120b: 89 4d ec mov %ecx,-0x14(%ebp) ; ptr to retval space for struct (hidden first arg) -> local area | |
257 120e: 89 55 e8 mov %edx,-0x18(%ebp) ; in arg 0 -> local area | |
258 1211: 66 c7 45 fc 0d 00 movw $0xd,-0x4(%ebp) ; | | |
259 1217: 66 c7 45 fe 0f 00 movw $0xf,-0x2(%ebp) ; | struct values (local area) | |
260 121d: 8b 45 ec mov -0x14(%ebp),%eax ; ptr to retval space for struct (fetched from local area) -> eax | |
261 1220: 8b 55 fc mov -0x4(%ebp),%edx ; | | |
262 1223: 89 10 mov %edx,(%eax) ; | copy struct in local area to retval space | |
263 1225: 8b 45 ec mov -0x14(%ebp),%eax ; return value (passed-in hidden ptr) | |
264 1228: c9 leave ; | | |
265 1229: c2 04 00 ret $0x4 ; | epilog | |
266 | |
267 0000122c <main>: | |
268 122c: 55 push %ebp ; | | |
269 122d: 89 e5 mov %esp,%ebp ; | prolog | |
270 122f: 83 ec 04 sub $0x4,%esp ; | | |
271 1232: 8d 45 fc lea -0x4(%ebp),%eax ; ptr to space used for struct retval (passed as hidden first arg) | |
272 1235: 6a 02 push $0x2 ; arg 1 | |
273 1237: ba 63 00 00 00 mov $0x63,%edx ; arg 0 (via reg) | |
274 123c: 89 c1 mov %eax,%ecx ; ptr to free space for call's retval (struct), hidden first arg | |
275 123e: e8 c2 ff ff ff call 1205 <leaf_call> ; push return address and call | |
276 1243: b8 00 00 00 00 mov $0x0,%eax ; return value | |
277 1248: c9 leave ; | | |
278 1249: c3 ret ; | epilog | |
279 | |
280 | |
281 | |
497
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
282 ; ---------- C++ trivial and non-trivial aggrs passed to C funcs ----------> |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
283 ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
284 ; struct Trivial { int a; }; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
285 ; struct NonTrivial { |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
286 ; int a; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
287 ; __attribute__((fastcall)) NonTrivial() : a(0) {} |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
288 ; __attribute__((fastcall)) NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
289 ; }; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
290 ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
291 ; extern "C" { |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
292 ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
293 ; void __attribute__((fastcall)) f1(struct Trivial s) { } |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
294 ; void __attribute__((fastcall)) f2(struct NonTrivial s) { } |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
295 ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
296 ; void __attribute__((fastcall)) f() |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
297 ; { |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
298 ; struct Trivial t; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
299 ; struct NonTrivial n; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
300 ; int a=1; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
301 ; a += 123; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
302 ; f1(t); |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
303 ; a -= 123; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
304 ; f2(n); |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
305 ; a -= 12; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
306 ; } |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
307 ; } |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
308 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
309 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
310 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
311 ; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
312 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
313 00001215 <f1>: |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
314 1215: 55 push %ebp |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
315 1216: 89 e5 mov %esp,%ebp |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
316 1218: e8 f0 ff ff ff call 120d <__x86.get_pc_thunk.ax> |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
317 121d: 05 af 2d 00 00 add $0x2daf,%eax |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
318 1222: 90 nop |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
319 1223: 5d pop %ebp |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
320 1224: c2 04 00 ret $0x4 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
321 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
322 00001227 <f2>: |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
323 1227: 55 push %ebp |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
324 1228: 89 e5 mov %esp,%ebp |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
325 122a: 83 ec 04 sub $0x4,%esp |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
326 122d: e8 db ff ff ff call 120d <__x86.get_pc_thunk.ax> |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
327 1232: 05 9a 2d 00 00 add $0x2d9a,%eax |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
328 1237: 89 4d fc mov %ecx,-0x4(%ebp) |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
329 123a: 90 nop |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
330 123b: c9 leave |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
331 123c: c3 ret |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
332 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
333 0000123d <f>: |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
334 123d: 55 push %ebp ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
335 123e: 89 e5 mov %esp,%ebp ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
336 1240: 83 ec 28 sub $0x28,%esp ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
337 1243: e8 c5 ff ff ff call 120d <__x86.get_pc_thunk.ax> ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
338 1248: 05 84 2d 00 00 add $0x2d84,%eax ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
339 124d: 65 a1 14 00 00 00 mov %gs:0x14,%eax ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
340 1253: 89 45 f4 mov %eax,-0xc(%ebp) ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
341 1256: 31 c0 xor %eax,%eax ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
342 1258: 8d 45 e8 lea -0x18(%ebp),%eax ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
343 125b: 89 c1 mov %eax,%ecx ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
344 125d: e8 60 00 00 00 call 12c2 <_ZN10NonTrivialC1Ev> ; NonTrivial::NonTrivial() / ctor |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
345 1262: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
346 1269: 83 45 f0 7b addl $0x7b,-0x10(%ebp) ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
347 126d: 83 ec 0c sub $0xc,%esp ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
348 1270: ff 75 e4 pushl -0x1c(%ebp) ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
349 1273: e8 9d ff ff ff call 1215 <f1> ; call f1(struct Trivial) |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
350 1278: 83 c4 0c add $0xc,%esp ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
351 127b: 83 6d f0 7b subl $0x7b,-0x10(%ebp) ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
352 127f: 8d 55 e8 lea -0x18(%ebp),%edx ; | ptr to n |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
353 1282: 8d 45 ec lea -0x14(%ebp),%eax ; | | |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
354 1285: 89 c1 mov %eax,%ecx ; | copy n | ptr to dest of copy of n |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
355 1287: e8 56 00 00 00 call 12e2 <_ZN10NonTrivialC1ERKS_> ; / NonTrivial::NonTrivial(const NonTrivial&) / copy ctor |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
356 128c: 8d 45 ec lea -0x14(%ebp),%eax ; \ |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
357 128f: 89 c1 mov %eax,%ecx ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
358 1291: e8 91 ff ff ff call 1227 <f2> ; call f2(struct NonTrivial) |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
359 1296: 83 6d f0 0c subl $0xc,-0x10(%ebp) ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
360 129a: 90 nop ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
361 129b: 8b 45 f4 mov -0xc(%ebp),%eax ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
362 129e: 65 33 05 14 00 00 00 xor %gs:0x14,%eax ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
363 12a5: 74 05 je 12ac <f+0x6f> ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
364 12a7: e8 59 00 00 00 call 1305 <__stack_chk_fail_local> ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
365 12ac: c9 leave ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
366 12ad: c3 ret ; |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
367 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
368 ; ... snip, removed code of ctor and copy ctor ... |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
369 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
370 |
cb19b2fe2422
- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
Tassilo Philipp
parents:
470
diff
changeset
|
371 |
470 | 372 ; vim: ft=asm |
373 |