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