Mercurial > pub > dyncall > dyncall
comparison doc/disas_examples/x64.win.disas @ 468:79b95db3d68f
- added (only partly annotated) x64/win64 disas examples
author | Tassilo Philipp |
---|---|
date | Sun, 06 Feb 2022 17:22:59 +0100 |
parents | c0390dc85a07 |
children | 75cb8f79d725 |
comparison
equal
deleted
inserted
replaced
467:b47168dacba6 | 468:79b95db3d68f |
---|---|
1 ; @@@ missing | 1 ; void leaf_call(int b, int c, int d, int e, int f, int g, int h) |
2 ; { | |
3 ; } | |
4 ; | |
5 ; void nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h) | |
6 ; { | |
7 ; /* use some local data */ | |
8 ; char x[10] = { 'L' }; | |
9 ; leaf_call(b, c, d, e, f, g, h); | |
10 ; } | |
11 ; | |
12 ; int main() | |
13 ; { | |
14 ; nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7); | |
15 ; return 0; | |
16 ; } | |
17 | |
18 | |
19 | |
20 ; output from godbolt compiler explorer w/ msvc 19.0 | |
21 | |
22 leaf_call PROC | |
23 mov DWORD PTR [rsp+32], r9d | |
24 mov DWORD PTR [rsp+24], r8d | |
25 mov DWORD PTR [rsp+16], edx | |
26 mov DWORD PTR [rsp+8], ecx | |
27 ret 0 | |
28 leaf_call ENDP | |
29 | |
30 x$ = 64 | |
31 b$ = 104 | |
32 c$ = 112 | |
33 d$ = 120 | |
34 e$ = 128 | |
35 f$ = 136 | |
36 g$ = 144 | |
37 h$ = 152 | |
38 nonleaf_call PROC | |
39 mov DWORD PTR [rsp+32], r9d ; | | | |
40 mov DWORD PTR [rsp+24], r8d ; | | | |
41 mov DWORD PTR [rsp+16], edx ; | | spill | |
42 mov DWORD PTR [rsp+8], ecx ; | | | |
43 push rdi ; | | |
44 sub rsp, 80 ; | prolog | |
45 mov BYTE PTR x$[rsp], 76 ; 'L' -> local area (of local array's space) | |
46 lea rax, QWORD PTR x$[rsp+1] ; | | |
47 mov rdi, rax ; | | |
48 xor eax, eax ; | zero-init rest of local array's space | |
49 mov ecx, 9 ; | | |
50 rep stosb ; | | |
51 mov eax, DWORD PTR h$[rsp] ; arg 6 (fetched from caller's frame param area), and ... | |
52 mov DWORD PTR [rsp+48], eax ; ... "pushed" onto stack | |
53 mov eax, DWORD PTR g$[rsp] ; arg 5 (fetched from caller's frame param area), and ... | |
54 mov DWORD PTR [rsp+40], eax ; ... "pushed" onto stack | |
55 mov eax, DWORD PTR f$[rsp] ; arg 4 (fetched from caller's frame param area), and ... | |
56 mov DWORD PTR [rsp+32], eax ; ... "pushed" onto stack | |
57 mov r9d, DWORD PTR e$[rsp] ; arg 3 | |
58 mov r8d, DWORD PTR d$[rsp] ; arg 2 | |
59 mov edx, DWORD PTR c$[rsp] ; arg 1 | |
60 mov ecx, DWORD PTR b$[rsp] ; arg 0 | |
61 call leaf_call ; push return addr and call | |
62 add rsp, 80 ; | | |
63 pop rdi ; | epilog | |
64 ret 0 ; | | |
65 nonleaf_call ENDP | |
66 | |
67 main PROC | |
68 sub rsp, 72 ; prolog | |
69 mov DWORD PTR [rsp+56], 7 ; "push" arg 7 onto stack | |
70 mov DWORD PTR [rsp+48], 6 ; "push" arg 6 onto stack | |
71 mov DWORD PTR [rsp+40], 5 ; "push" arg 5 onto stack | |
72 mov DWORD PTR [rsp+32], 4 ; "push" arg 4 onto stack | |
73 mov r9d, 3 ; arg 3 | |
74 mov r8d, 2 ; arg 2 | |
75 mov edx, 1 ; arg 1 | |
76 xor ecx, ecx ; arg 0 | |
77 call nonleaf_call ; push return addr and call | |
78 xor eax, eax ; return value | |
79 add rsp, 72 ; | | |
80 ret 0 ; | epilog | |
81 main ENDP | |
82 | |
83 | |
84 | |
85 ; ---------- structs by value, struct in first call on reg arg boundary ----------> | |
86 ; | |
87 ; struct A { int i, j; long long l; }; | |
88 ; | |
89 ; void leaf_call(int b, int c, int d, int e, struct A f, int g, int h) | |
90 ; { | |
91 ; } | |
92 ; | |
93 ; void nonleaf_call(int a, int b, int c, int d, int e, struct A f, int g, int h) | |
94 ; { | |
95 ; /* use some local data */ | |
96 ; char x[220] = { 'L' }; | |
97 ; leaf_call(b, c, d, e, f, g, h); | |
98 ; } | |
99 ; | |
100 ; int main() | |
101 ; { | |
102 ; struct A a = {5, 6, 7ll}; | |
103 ; nonleaf_call(0, 1, 2, 3, 4, a, 8, 9); | |
104 ; return 0; | |
105 ; } | |
106 | |
107 | |
108 | |
109 ; output from godbolt compiler explorer w/ msvc 19.0 | |
110 | |
111 leaf_call PROC | |
112 mov DWORD PTR [rsp+32], r9d | |
113 mov DWORD PTR [rsp+24], r8d | |
114 mov DWORD PTR [rsp+16], edx | |
115 mov DWORD PTR [rsp+8], ecx | |
116 ret 0 | |
117 leaf_call ENDP | |
118 | |
119 $T1 = 64 | |
120 x$ = 80 | |
121 b$ = 344 | |
122 c$ = 352 | |
123 d$ = 360 | |
124 e$ = 368 | |
125 f$ = 376 | |
126 g$ = 384 | |
127 h$ = 392 | |
128 nonleaf_call PROC | |
129 mov DWORD PTR [rsp+32], r9d | |
130 mov DWORD PTR [rsp+24], r8d | |
131 mov DWORD PTR [rsp+16], edx | |
132 mov DWORD PTR [rsp+8], ecx | |
133 push rsi | |
134 push rdi | |
135 sub rsp, 312 ; 00000138H | |
136 mov BYTE PTR x$[rsp], 76 ; 0000004cH | |
137 lea rax, QWORD PTR x$[rsp+1] | |
138 mov rdi, rax | |
139 xor eax, eax | |
140 mov ecx, 219 ; 000000dbH | |
141 rep stosb | |
142 lea rax, QWORD PTR $T1[rsp] | |
143 mov rdi, rax | |
144 mov rsi, QWORD PTR f$[rsp] | |
145 mov ecx, 16 | |
146 rep movsb | |
147 mov eax, DWORD PTR h$[rsp] | |
148 mov DWORD PTR [rsp+48], eax | |
149 mov eax, DWORD PTR g$[rsp] | |
150 mov DWORD PTR [rsp+40], eax | |
151 lea rax, QWORD PTR $T1[rsp] | |
152 mov QWORD PTR [rsp+32], rax | |
153 mov r9d, DWORD PTR e$[rsp] | |
154 mov r8d, DWORD PTR d$[rsp] | |
155 mov edx, DWORD PTR c$[rsp] | |
156 mov ecx, DWORD PTR b$[rsp] | |
157 call leaf_call | |
158 add rsp, 312 ; 00000138H | |
159 pop rdi | |
160 pop rsi | |
161 ret 0 | |
162 nonleaf_call ENDP | |
163 | |
164 a$ = 64 | |
165 $T1 = 80 | |
166 main PROC | |
167 push rsi | |
168 push rdi | |
169 sub rsp, 104 ; 00000068H | |
170 mov DWORD PTR a$[rsp], 5 | |
171 mov DWORD PTR a$[rsp+4], 6 | |
172 mov QWORD PTR a$[rsp+8], 7 | |
173 lea rax, QWORD PTR $T1[rsp] | |
174 lea rcx, QWORD PTR a$[rsp] | |
175 mov rdi, rax | |
176 mov rsi, rcx | |
177 mov ecx, 16 | |
178 rep movsb | |
179 mov DWORD PTR [rsp+56], 9 | |
180 mov DWORD PTR [rsp+48], 8 | |
181 lea rax, QWORD PTR $T1[rsp] | |
182 mov QWORD PTR [rsp+40], rax | |
183 mov DWORD PTR [rsp+32], 4 | |
184 mov r9d, 3 | |
185 mov r8d, 2 | |
186 mov edx, 1 | |
187 xor ecx, ecx | |
188 call nonleaf_call | |
189 xor eax, eax | |
190 add rsp, 104 ; 00000068H | |
191 pop rdi | |
192 pop rsi | |
193 ret 0 | |
194 main ENDP | |
195 | |
196 | |
197 | |
198 ; ---------- structs by value, complex example (multiple structs, partly passed via regs) ----------> | |
199 ; | |
200 ; struct A { int i, j; float f; }; | |
201 ; struct B { double d; long long l; }; | |
202 ; | |
203 ; void leaf_call(int b, struct A c, struct B d, int e, int f, struct A g, struct B h, int i, int j) | |
204 ; { | |
205 ; } | |
206 ; | |
207 ; void nonleaf_call(int a, int b, struct A c, struct B d, int e, int f, struct A g, struct B h, int i, int j) | |
208 ; { | |
209 ; /* use some local data */ | |
210 ; char x[220] = { 'L' }; | |
211 ; leaf_call(b, c, d, e, f, g, h, i, j); | |
212 ; } | |
213 ; | |
214 ; int main() | |
215 ; { | |
216 ; struct A a = {2, 3, 4.f}; | |
217 ; struct B b = {5., 6ll}; | |
218 ; struct A c = {9, 10, 11.f}; | |
219 ; struct B d = {12., 13ll}; | |
220 ; nonleaf_call(0, 1, a, b, 7, 8, c, d, 14, 15); | |
221 ; return 0; | |
222 ; } | |
223 | |
224 | |
225 | |
226 ; output from godbolt compiler explorer w/ msvc 19.0 | |
227 | |
228 __real@41300000 DD 041300000r ; | | |
229 __real@40800000 DD 040800000r ; | | |
230 __real@4028000000000000 DQ 04028000000000000r ; | fp data | |
231 __real@4014000000000000 DQ 04014000000000000r ; | | |
232 | |
233 leaf_call PROC | |
234 mov DWORD PTR [rsp+32], r9d | |
235 mov QWORD PTR [rsp+24], r8 | |
236 mov QWORD PTR [rsp+16], rdx | |
237 mov DWORD PTR [rsp+8], ecx | |
238 ret 0 | |
239 leaf_call ENDP | |
240 | |
241 $T1 = 80 | |
242 $T2 = 96 | |
243 $T3 = 112 | |
244 $T4 = 128 | |
245 x$ = 144 | |
246 b$ = 408 | |
247 c$ = 416 | |
248 d$ = 424 | |
249 e$ = 432 | |
250 f$ = 440 | |
251 g$ = 448 | |
252 h$ = 456 | |
253 i$ = 464 | |
254 j$ = 472 | |
255 nonleaf_call PROC | |
256 mov QWORD PTR [rsp+32], r9 | |
257 mov QWORD PTR [rsp+24], r8 | |
258 mov DWORD PTR [rsp+16], edx | |
259 mov DWORD PTR [rsp+8], ecx | |
260 push rsi | |
261 push rdi | |
262 sub rsp, 376 | |
263 mov BYTE PTR x$[rsp], 76 | |
264 lea rax, QWORD PTR x$[rsp+1] | |
265 mov rdi, rax | |
266 xor eax, eax | |
267 mov ecx, 219 | |
268 rep stosb | |
269 lea rax, QWORD PTR $T3[rsp] | |
270 mov rdi, rax | |
271 mov rsi, QWORD PTR h$[rsp] | |
272 mov ecx, 16 | |
273 rep movsb | |
274 lea rax, QWORD PTR $T1[rsp] | |
275 mov rdi, rax | |
276 mov rsi, QWORD PTR g$[rsp] | |
277 mov ecx, 12 | |
278 rep movsb | |
279 lea rax, QWORD PTR $T4[rsp] | |
280 mov rdi, rax | |
281 mov rsi, QWORD PTR d$[rsp] | |
282 mov ecx, 16 | |
283 rep movsb | |
284 lea rax, QWORD PTR $T2[rsp] | |
285 mov rdi, rax | |
286 mov rsi, QWORD PTR c$[rsp] | |
287 mov ecx, 12 | |
288 rep movsb | |
289 mov eax, DWORD PTR j$[rsp] | |
290 mov DWORD PTR [rsp+64], eax | |
291 mov eax, DWORD PTR i$[rsp] | |
292 mov DWORD PTR [rsp+56], eax | |
293 lea rax, QWORD PTR $T3[rsp] | |
294 mov QWORD PTR [rsp+48], rax | |
295 lea rax, QWORD PTR $T1[rsp] | |
296 mov QWORD PTR [rsp+40], rax | |
297 mov eax, DWORD PTR f$[rsp] | |
298 mov DWORD PTR [rsp+32], eax | |
299 mov r9d, DWORD PTR e$[rsp] | |
300 lea r8, QWORD PTR $T4[rsp] | |
301 lea rdx, QWORD PTR $T2[rsp] | |
302 mov ecx, DWORD PTR b$[rsp] | |
303 call leaf_call | |
304 add rsp, 376 | |
305 pop rdi | |
306 pop rsi | |
307 ret 0 | |
308 nonleaf_call ENDP | |
309 | |
310 c$ = 80 | |
311 a$ = 96 | |
312 $T1 = 112 | |
313 $T2 = 128 | |
314 d$ = 144 | |
315 b$ = 160 | |
316 $T3 = 176 | |
317 $T4 = 192 | |
318 main PROC | |
319 push rsi | |
320 push rdi | |
321 sub rsp, 216 | |
322 mov DWORD PTR a$[rsp], 2 | |
323 mov DWORD PTR a$[rsp+4], 3 | |
324 movss xmm0, DWORD PTR __real@40800000 | |
325 movss DWORD PTR a$[rsp+8], xmm0 | |
326 movsd xmm0, QWORD PTR __real@4014000000000000 | |
327 movsd QWORD PTR b$[rsp], xmm0 | |
328 mov QWORD PTR b$[rsp+8], 6 | |
329 mov DWORD PTR c$[rsp], 9 | |
330 mov DWORD PTR c$[rsp+4], 10 | |
331 movss xmm0, DWORD PTR __real@41300000 | |
332 movss DWORD PTR c$[rsp+8], xmm0 | |
333 movsd xmm0, QWORD PTR __real@4028000000000000 | |
334 movsd QWORD PTR d$[rsp], xmm0 | |
335 mov QWORD PTR d$[rsp+8], 13 | |
336 lea rax, QWORD PTR $T3[rsp] | |
337 lea rcx, QWORD PTR d$[rsp] | |
338 mov rdi, rax | |
339 mov rsi, rcx | |
340 mov ecx, 16 | |
341 rep movsb | |
342 lea rax, QWORD PTR $T1[rsp] | |
343 lea rcx, QWORD PTR c$[rsp] | |
344 mov rdi, rax | |
345 mov rsi, rcx | |
346 mov ecx, 12 | |
347 rep movsb | |
348 lea rax, QWORD PTR $T4[rsp] | |
349 lea rcx, QWORD PTR b$[rsp] | |
350 mov rdi, rax | |
351 mov rsi, rcx | |
352 mov ecx, 16 | |
353 rep movsb | |
354 lea rax, QWORD PTR $T2[rsp] | |
355 lea rcx, QWORD PTR a$[rsp] | |
356 mov rdi, rax | |
357 mov rsi, rcx | |
358 mov ecx, 12 | |
359 rep movsb | |
360 mov DWORD PTR [rsp+72], 15 | |
361 mov DWORD PTR [rsp+64], 14 | |
362 lea rax, QWORD PTR $T3[rsp] | |
363 mov QWORD PTR [rsp+56], rax | |
364 lea rax, QWORD PTR $T1[rsp] | |
365 mov QWORD PTR [rsp+48], rax | |
366 mov DWORD PTR [rsp+40], 8 | |
367 mov DWORD PTR [rsp+32], 7 | |
368 lea r9, QWORD PTR $T4[rsp] | |
369 lea r8, QWORD PTR $T2[rsp] | |
370 mov edx, 1 | |
371 xor ecx, ecx | |
372 call nonleaf_call | |
373 xor eax, eax | |
374 add rsp, 216 | |
375 pop rdi | |
376 pop rsi | |
377 ret 0 | |
378 main ENDP | |
379 | |
380 | |
381 | |
382 ; ---------- returning tiny struct by value (passes via regs) ----------> | |
383 ; | |
384 ; struct A { unsigned char a; }; | |
385 ; | |
386 ; struct A call(unsigned char c) | |
387 ; { | |
388 ; struct A r = {c}; | |
389 ; return r; | |
390 ; } | |
391 ; | |
392 ; int main() | |
393 ; { | |
394 ; struct A a = call(123); | |
395 ; return 0; | |
396 ; } | |
397 | |
398 | |
399 | |
400 ; output from godbolt compiler explorer w/ msvc 19.0 | |
401 | |
402 r$ = 0 | |
403 c$ = 32 | |
404 call PROC | |
405 mov BYTE PTR [rsp+8], cl ; | spill | |
406 sub rsp, 24 ; | prolog | |
407 movzx eax, BYTE PTR c$[rsp] ; in arg 0 (fetched from spill area) -> eax, then ... | |
408 mov BYTE PTR r$[rsp], al ; ... -> struct in local area (top of stack, as leaf call and thus no reserved spill area) | |
409 movzx eax, BYTE PTR r$[rsp] ; reget same value into eax to return (small) struct via reg (a bit pointless to refetch) | |
410 add rsp, 24 ; | | |
411 ret 0 ; | epilog | |
412 call ENDP | |
413 | |
414 a$ = 32 | |
415 main PROC | |
416 sub rsp, 56 ; prolog | |
417 mov cl, 123 ; arg 0 | |
418 call call ; push return addr and call | |
419 mov BYTE PTR a$[rsp], al ; write struct data to local area (123) | |
420 xor eax, eax ; return value | |
421 add rsp, 56 ; | | |
422 ret 0 ; | epilog | |
423 main ENDP | |
424 | |
425 | |
426 ; vim: ft=asm | |
427 |