# HG changeset patch # User Tassilo Philipp # Date 1664790036 -7200 # Node ID f1810b5dbb3bc89cafee774934e4a9480eca094f # Parent 6a34dcb2bbd7d57bcb7b9a1384d2a035e9f8f288 sysv x64 disas examples: - fixed comments - example passing aggregate as vararg diff -r 6a34dcb2bbd7 -r f1810b5dbb3b doc/disas_examples/x64.sysv.disas --- a/doc/disas_examples/x64.sysv.disas Sun Oct 02 16:45:06 2022 +0200 +++ b/doc/disas_examples/x64.sysv.disas Mon Oct 03 11:40:36 2022 +0200 @@ -220,18 +220,18 @@ 201981: 8b 75 ec mov -0x14(%rbp),%esi ; arg 1 201984: 8b 55 e8 mov -0x18(%rbp),%edx ; arg 2 201987: 8b 4d e4 mov -0x1c(%rbp),%ecx ; arg 3 - 20198a: 44 8b 45 e0 mov -0x20(%rbp),%r8d ; in arg 6 (local copy) -> r8 pointless, free regs available and using arg reg as temporary, needs freeing below - 20198e: 44 8b 4d 20 mov 0x20(%rbp),%r9d ; in arg 7 (stack) -> r9 pointless, free regs available and using arg reg as temporary, needs freeing below - 201992: 4d 8b 1a mov (%r10),%r11 ; in arg 5 (A.i, A.j) -> hold in scratch reg - 201995: 4d 8b 52 08 mov 0x8(%r10),%r10 ; in arg 5 (A.l) -> hold in scratch reg + 20198a: 44 8b 45 e0 mov -0x20(%rbp),%r8d ; in arg 5 (local copy) -> r8 pointless, free regs available and using arg reg as temporary, needs freeing below + 20198e: 44 8b 4d 20 mov 0x20(%rbp),%r9d ; in arg 6 (stack) -> r9 pointless, free regs available and using arg reg as temporary, needs freeing below + 201992: 4d 8b 1a mov (%r10),%r11 ; in arg 4 (A.i, A.j) -> hold in scratch reg + 201995: 4d 8b 52 08 mov 0x8(%r10),%r10 ; in arg 4 (A.l) -> hold in scratch reg 201999: 44 89 85 fc fe ff ff mov %r8d,-0x104(%rbp) ; 'free' r8, temp store content 2019a0: 4d 89 d8 mov %r11,%r8 ; arg 4 (A.i, A.j) 2019a3: 44 89 8d f8 fe ff ff mov %r9d,-0x108(%rbp) ; 'free' r9, temp store content 2019aa: 4d 89 d1 mov %r10,%r9 ; arg 4 (A.l) - 2019ad: 8b 9d fc fe ff ff mov -0x104(%rbp),%ebx ; \ + 2019ad: 8b 9d fc fe ff ff mov -0x104(%rbp),%ebx ; | 2019b3: 89 1c 24 mov %ebx,(%rsp) ; / arg 5 (fetch from temp store, pushed) pointless, could've been pushed, directly 2019b6: 8b 9d f8 fe ff ff mov -0x108(%rbp),%ebx ; \ - 2019bc: 89 5c 24 08 mov %ebx,0x8(%rsp) ; / arg 6 (fetch from temp store, pushed) pointless, could've been pushed, directly + 2019bc: 89 5c 24 08 mov %ebx,0x8(%rsp) ; | arg 6 (fetch from temp store, pushed) pointless, could've been pushed, directly 2019c0: 89 85 f4 fe ff ff mov %eax,-0x10c(%rbp) ; unsure... write something to local area @@@? 2019c6: e8 55 ff ff ff callq 201920 ; push return addr and call 2019cb: 48 81 c4 18 01 00 00 add $0x118,%rsp ; | @@ -667,5 +667,288 @@ + +; ---------- structs by value, struct passed as vararg ----------> +; +; #include +; #include +; +; struct A { int i, j; long long l; }; +; +; void leaf_call(int b, int c, int d, int e, ...) +; { +; } +; +; void nonleaf_call(int a, int b, int c, ...) +; { +; int d, e, g, h; +; struct A f; +; va_list ap; +; va_start(ap, c); +; d = va_arg(ap, int); +; e = va_arg(ap, int); +; f = va_arg(ap, struct A); +; g = va_arg(ap, int); +; h = va_arg(ap, int); +; /* use some local data */ +; *(char*)alloca(220) = 'L'; +; leaf_call(b, c, d, e, f, g, h); +; va_end(ap); +; } +; +; int main() +; { +; nonleaf_call(0, 1, 2, 3, 4, (struct A){5, 6, 7ll}, 8, 9); +; return 0; +; } + + + +; output from freebsd-12.2-x64 w/ clang 10.0.1 + +0000000000000000 : + 0: 55 push %rbp ; + 1: 48 89 e5 mov %rsp,%rbp ; + 4: 89 7d fc mov %edi,-0x4(%rbp) ; + 7: 89 75 f8 mov %esi,-0x8(%rbp) ; + a: 89 55 f4 mov %edx,-0xc(%rbp) ; + d: 89 4d f0 mov %ecx,-0x10(%rbp) ; + 10: 5d pop %rbp ; + 11: c3 retq ; + 12: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) ; + 19: 00 00 00 ; + 1c: 0f 1f 40 00 nopl 0x0(%rax) ; + +0000000000000020 : + 20: 55 push %rbp ; | + 21: 48 89 e5 mov %rsp,%rbp ; | prolog + 24: 53 push %rbx ; | + 25: 48 81 ec 28 02 00 00 sub $0x228,%rsp ; | open frame *with* static alloca() size included + 2c: 84 c0 test %al,%al ; test how many used xmm regs (= 0) + 2e: 0f 29 bd f0 fe ff ff movaps %xmm7,-0x110(%rbp) ; | + 35: 0f 29 b5 e0 fe ff ff movaps %xmm6,-0x120(%rbp) ; | + 3c: 0f 29 ad d0 fe ff ff movaps %xmm5,-0x130(%rbp) ; | + 43: 0f 29 a5 c0 fe ff ff movaps %xmm4,-0x140(%rbp) ; | spill xmm regs onto stack (none used by call, though) + 4a: 0f 29 9d b0 fe ff ff movaps %xmm3,-0x150(%rbp) ; | + 51: 0f 29 95 a0 fe ff ff movaps %xmm2,-0x160(%rbp) ; | + 58: 0f 29 8d 90 fe ff ff movaps %xmm1,-0x170(%rbp) ; | + 5f: 0f 29 85 80 fe ff ff movaps %xmm0,-0x180(%rbp) ; / + 66: 4c 89 8d 78 fe ff ff mov %r9,-0x188(%rbp) ; \ + 6d: 4c 89 85 70 fe ff ff mov %r8,-0x190(%rbp) ; | + 74: 48 89 8d 68 fe ff ff mov %rcx,-0x198(%rbp) ; | + 7b: 89 95 64 fe ff ff mov %edx,-0x19c(%rbp) ; | in args (regs) -> local area (as temp store, mem order 0,1,2,3,4,8) + 81: 89 b5 60 fe ff ff mov %esi,-0x1a0(%rbp) ; | + 87: 89 bd 5c fe ff ff mov %edi,-0x1a4(%rbp) ; | + 8d: 0f 84 67 00 00 00 je fa ; jump to 0xfa if no xmm regs used + 93: 0f 28 85 80 fe ff ff movaps -0x180(%rbp),%xmm0 ; + 9a: 0f 29 85 30 ff ff ff movaps %xmm0,-0xd0(%rbp) ; + a1: 0f 28 8d 90 fe ff ff movaps -0x170(%rbp),%xmm1 ; + a8: 0f 29 8d 40 ff ff ff movaps %xmm1,-0xc0(%rbp) ; + af: 0f 28 95 a0 fe ff ff movaps -0x160(%rbp),%xmm2 ; + b6: 0f 29 95 50 ff ff ff movaps %xmm2,-0xb0(%rbp) ; + bd: 0f 28 9d b0 fe ff ff movaps -0x150(%rbp),%xmm3 ; + c4: 0f 29 9d 60 ff ff ff movaps %xmm3,-0xa0(%rbp) ; + cb: 0f 28 a5 c0 fe ff ff movaps -0x140(%rbp),%xmm4 ; + d2: 0f 29 a5 70 ff ff ff movaps %xmm4,-0x90(%rbp) ; + d9: 0f 28 ad d0 fe ff ff movaps -0x130(%rbp),%xmm5 ; + e0: 0f 29 6d 80 movaps %xmm5,-0x80(%rbp) ; + e4: 0f 28 b5 e0 fe ff ff movaps -0x120(%rbp),%xmm6 ; + eb: 0f 29 75 90 movaps %xmm6,-0x70(%rbp) ; + ef: 0f 28 bd f0 fe ff ff movaps -0x110(%rbp),%xmm7 ; + f6: 0f 29 7d a0 movaps %xmm7,-0x60(%rbp) ; + fa: 48 8b 85 78 fe ff ff mov -0x188(%rbp),%rax ; je loc + 101: 48 89 85 28 ff ff ff mov %rax,-0xd8(%rbp) ; + 108: 48 8b 8d 70 fe ff ff mov -0x190(%rbp),%rcx ; + 10f: 48 89 8d 20 ff ff ff mov %rcx,-0xe0(%rbp) ; + 116: 48 8b 95 68 fe ff ff mov -0x198(%rbp),%rdx ; + 11d: 48 89 95 18 ff ff ff mov %rdx,-0xe8(%rbp) ; + 124: 48 8d 75 b0 lea -0x50(%rbp),%rsi ; + 128: 8b bd 5c fe ff ff mov -0x1a4(%rbp),%edi ; + 12e: 89 7d f4 mov %edi,-0xc(%rbp) ; + 131: 44 8b 85 60 fe ff ff mov -0x1a0(%rbp),%r8d ; + 138: 44 89 45 f0 mov %r8d,-0x10(%rbp) ; + 13c: 44 8b 8d 64 fe ff ff mov -0x19c(%rbp),%r9d ; + 143: 44 89 4d ec mov %r9d,-0x14(%rbp) ; + 147: 49 89 f2 mov %rsi,%r10 ; + 14a: 4c 8d 9d 00 ff ff ff lea -0x100(%rbp),%r11 ; + 151: 4d 89 5a 10 mov %r11,0x10(%r10) ; + 155: 4c 8d 5d 10 lea 0x10(%rbp),%r11 ; + 159: 4d 89 5a 08 mov %r11,0x8(%r10) ; + 15d: 41 c7 42 04 30 00 00 00 movl $0x30,0x4(%r10) ; + 165: 41 c7 02 18 00 00 00 movl $0x18,(%r10) ; + 16c: 8b 5d b0 mov -0x50(%rbp),%ebx ; + 16f: 83 fb 28 cmp $0x28,%ebx ; + 172: 48 89 b5 50 fe ff ff mov %rsi,-0x1b0(%rbp) ; + 179: 89 9d 4c fe ff ff mov %ebx,-0x1b4(%rbp) ; + 17f: 0f 87 25 00 00 00 ja 1aa ; + 185: 8b 85 4c fe ff ff mov -0x1b4(%rbp),%eax ; + 18b: 48 63 c8 movslq %eax,%rcx ; + 18e: 48 8b 95 50 fe ff ff mov -0x1b0(%rbp),%rdx ; + 195: 48 03 4a 10 add 0x10(%rdx),%rcx ; + 199: 83 c0 08 add $0x8,%eax ; + 19c: 89 02 mov %eax,(%rdx) ; + 19e: 48 89 8d 40 fe ff ff mov %rcx,-0x1c0(%rbp) ; + 1a5: e9 20 00 00 00 jmpq 1ca ; + 1aa: 48 8b 85 50 fe ff ff mov -0x1b0(%rbp),%rax ; + 1b1: 48 8b 48 08 mov 0x8(%rax),%rcx ; + 1b5: 48 89 ca mov %rcx,%rdx ; + 1b8: 48 81 c1 08 00 00 00 add $0x8,%rcx ; + 1bf: 48 89 48 08 mov %rcx,0x8(%rax) ; + 1c3: 48 89 95 40 fe ff ff mov %rdx,-0x1c0(%rbp) ; + 1ca: 48 8b 85 40 fe ff ff mov -0x1c0(%rbp),%rax ; + 1d1: 48 8d 4d b0 lea -0x50(%rbp),%rcx ; + 1d5: 8b 10 mov (%rax),%edx ; + 1d7: 89 55 e8 mov %edx,-0x18(%rbp) ; + 1da: 8b 55 b0 mov -0x50(%rbp),%edx ; + 1dd: 83 fa 28 cmp $0x28,%edx ; + 1e0: 48 89 8d 38 fe ff ff mov %rcx,-0x1c8(%rbp) ; + 1e7: 89 95 34 fe ff ff mov %edx,-0x1cc(%rbp) ; + 1ed: 0f 87 25 00 00 00 ja 218 ; + 1f3: 8b 85 34 fe ff ff mov -0x1cc(%rbp),%eax ; + 1f9: 48 63 c8 movslq %eax,%rcx ; + 1fc: 48 8b 95 38 fe ff ff mov -0x1c8(%rbp),%rdx ; + 203: 48 03 4a 10 add 0x10(%rdx),%rcx ; + 207: 83 c0 08 add $0x8,%eax ; + 20a: 89 02 mov %eax,(%rdx) ; + 20c: 48 89 8d 28 fe ff ff mov %rcx,-0x1d8(%rbp) ; + 213: e9 20 00 00 00 jmpq 238 ; + 218: 48 8b 85 38 fe ff ff mov -0x1c8(%rbp),%rax ; + 21f: 48 8b 48 08 mov 0x8(%rax),%rcx ; + 223: 48 89 ca mov %rcx,%rdx ; + 226: 48 81 c1 08 00 00 00 add $0x8,%rcx ; + 22d: 48 89 48 08 mov %rcx,0x8(%rax) ; + 231: 48 89 95 28 fe ff ff mov %rdx,-0x1d8(%rbp) ; + 238: 48 8b 85 28 fe ff ff mov -0x1d8(%rbp),%rax ; + 23f: 48 8d 4d b0 lea -0x50(%rbp),%rcx ; + 243: 8b 10 mov (%rax),%edx ; + 245: 89 55 e4 mov %edx,-0x1c(%rbp) ; + 248: 8b 55 b0 mov -0x50(%rbp),%edx ; + 24b: 83 fa 20 cmp $0x20,%edx ; + 24e: 48 89 8d 20 fe ff ff mov %rcx,-0x1e0(%rbp) ; + 255: 89 95 1c fe ff ff mov %edx,-0x1e4(%rbp) ; + 25b: 0f 87 25 00 00 00 ja 286 ; + 261: 8b 85 1c fe ff ff mov -0x1e4(%rbp),%eax ; + 267: 48 63 c8 movslq %eax,%rcx ; + 26a: 48 8b 95 20 fe ff ff mov -0x1e0(%rbp),%rdx ; + 271: 48 03 4a 10 add 0x10(%rdx),%rcx ; + 275: 83 c0 10 add $0x10,%eax ; + 278: 89 02 mov %eax,(%rdx) ; + 27a: 48 89 8d 10 fe ff ff mov %rcx,-0x1f0(%rbp) ; + 281: e9 20 00 00 00 jmpq 2a6 ; + 286: 48 8b 85 20 fe ff ff mov -0x1e0(%rbp),%rax ; + 28d: 48 8b 48 08 mov 0x8(%rax),%rcx ; + 291: 48 89 ca mov %rcx,%rdx ; + 294: 48 81 c1 10 00 00 00 add $0x10,%rcx ; + 29b: 48 89 48 08 mov %rcx,0x8(%rax) ; + 29f: 48 89 95 10 fe ff ff mov %rdx,-0x1f0(%rbp) ; + 2a6: 48 8b 85 10 fe ff ff mov -0x1f0(%rbp),%rax ; + 2ad: 48 8d 4d b0 lea -0x50(%rbp),%rcx ; + 2b1: 48 8b 10 mov (%rax),%rdx ; + 2b4: 48 89 55 c8 mov %rdx,-0x38(%rbp) ; + 2b8: 48 8b 40 08 mov 0x8(%rax),%rax ; + 2bc: 48 89 45 d0 mov %rax,-0x30(%rbp) ; + 2c0: 8b 75 b0 mov -0x50(%rbp),%esi ; + 2c3: 83 fe 28 cmp $0x28,%esi ; + 2c6: 48 89 8d 08 fe ff ff mov %rcx,-0x1f8(%rbp) ; + 2cd: 89 b5 04 fe ff ff mov %esi,-0x1fc(%rbp) ; + 2d3: 0f 87 25 00 00 00 ja 2fe ; + 2d9: 8b 85 04 fe ff ff mov -0x1fc(%rbp),%eax ; + 2df: 48 63 c8 movslq %eax,%rcx ; + 2e2: 48 8b 95 08 fe ff ff mov -0x1f8(%rbp),%rdx ; + 2e9: 48 03 4a 10 add 0x10(%rdx),%rcx ; + 2ed: 83 c0 08 add $0x8,%eax ; + 2f0: 89 02 mov %eax,(%rdx) ; + 2f2: 48 89 8d f8 fd ff ff mov %rcx,-0x208(%rbp) ; + 2f9: e9 20 00 00 00 jmpq 31e ; + 2fe: 48 8b 85 08 fe ff ff mov -0x1f8(%rbp),%rax ; + 305: 48 8b 48 08 mov 0x8(%rax),%rcx ; + 309: 48 89 ca mov %rcx,%rdx ; + 30c: 48 81 c1 08 00 00 00 add $0x8,%rcx ; + 313: 48 89 48 08 mov %rcx,0x8(%rax) ; + 317: 48 89 95 f8 fd ff ff mov %rdx,-0x208(%rbp) ; + 31e: 48 8b 85 f8 fd ff ff mov -0x208(%rbp),%rax ; + 325: 48 8d 4d b0 lea -0x50(%rbp),%rcx ; + 329: 8b 10 mov (%rax),%edx ; + 32b: 89 55 e0 mov %edx,-0x20(%rbp) ; + 32e: 8b 55 b0 mov -0x50(%rbp),%edx ; + 331: 83 fa 28 cmp $0x28,%edx ; + 334: 48 89 8d f0 fd ff ff mov %rcx,-0x210(%rbp) ; + 33b: 89 95 ec fd ff ff mov %edx,-0x214(%rbp) ; + 341: 0f 87 25 00 00 00 ja 36c ; + 347: 8b 85 ec fd ff ff mov -0x214(%rbp),%eax ; + 34d: 48 63 c8 movslq %eax,%rcx ; + 350: 48 8b 95 f0 fd ff ff mov -0x210(%rbp),%rdx ; + 357: 48 03 4a 10 add 0x10(%rdx),%rcx ; + 35b: 83 c0 08 add $0x8,%eax ; + 35e: 89 02 mov %eax,(%rdx) ; + 360: 48 89 8d e0 fd ff ff mov %rcx,-0x220(%rbp) ; + 367: e9 20 00 00 00 jmpq 38c ; + 36c: 48 8b 85 f0 fd ff ff mov -0x210(%rbp),%rax ; + 373: 48 8b 48 08 mov 0x8(%rax),%rcx ; + 377: 48 89 ca mov %rcx,%rdx ; + 37a: 48 81 c1 08 00 00 00 add $0x8,%rcx ; + 381: 48 89 48 08 mov %rcx,0x8(%rax) ; + 385: 48 89 95 e0 fd ff ff mov %rdx,-0x220(%rbp) ; + 38c: 48 8b 85 e0 fd ff ff mov -0x220(%rbp),%rax ; + 393: 8b 08 mov (%rax),%ecx ; + 395: 89 4d dc mov %ecx,-0x24(%rbp) ; + 398: 48 89 e0 mov %rsp,%rax ; + 39b: 48 89 c2 mov %rax,%rdx ; + 39e: 48 81 c2 20 ff ff ff add $0xffffffffffffff20,%rdx ; + 3a5: 48 89 d4 mov %rdx,%rsp ; + 3a8: c6 80 20 ff ff ff 4c movb $0x4c,-0xe0(%rax) ; 'L' -> local area (of alloca()'d space) + 3af: 8b 7d f0 mov -0x10(%rbp),%edi ; arg 0 + 3b2: 8b 75 ec mov -0x14(%rbp),%esi ; arg 1 + 3b5: 8b 55 e8 mov -0x18(%rbp),%edx ; arg 2 + 3b8: 8b 4d e4 mov -0x1c(%rbp),%ecx ; arg 3 + 3bb: 44 8b 45 e0 mov -0x20(%rbp),%r8d ; in arg 5 (local copy) -> r8 pointless, free regs available and using arg reg as temporary, needs freeing below + 3bf: 44 8b 4d dc mov -0x24(%rbp),%r9d ; in arg 6 (stack) -> r9 pointless, free regs available and using arg reg as temporary, needs freeing below + 3c3: 48 8b 45 c8 mov -0x38(%rbp),%rax ; in arg 4 (A.i, A.j) -> hold in scratch reg + 3c7: 4c 8b 55 d0 mov -0x30(%rbp),%r10 ; in arg 4 (A.l) -> hold in scratch reg + 3cb: 48 83 ec 10 sub $0x10,%rsp ; | stack space to pass arg 5 and 6, access ptr in r11 + 3cf: 49 89 e3 mov %rsp,%r11 ; | + 3d2: 45 89 4b 08 mov %r9d,0x8(%r11) ; 'push' arg 5, 'frees' r9 implicitly + 3d6: 45 89 03 mov %r8d,(%r11) ; 'push' arg 6, 'frees' r8 implicitly + 3d9: 45 31 c0 xor %r8d,%r8d ; | + 3dc: 44 88 85 df fd ff ff mov %r8b,-0x221(%rbp) ; | number of used xmm registers (0) -> temp store (see below) + 3e3: 49 89 c0 mov %rax,%r8 ; arg 4 (A.i, A.j) | + 3e6: 4d 89 d1 mov %r10,%r9 ; arg 4 (A.l) | struct passed in regs, regardless of it being a vararg + 3e9: 8a 85 df fd ff ff mov -0x221(%rbp),%al ; number of used xmm registers (upper bound, req for varargs) + 3ef: e8 00 00 00 00 callq 3f4 ; push return addr and call + 3f4: 48 8d 65 f8 lea -0x8(%rbp),%rsp ; | + 3f8: 5b pop %rbx ; | + 3f9: 5d pop %rbp ; | epilog + 3fa: c3 retq ; | + 3fb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) ; garbage data + +0000000000000400
: + 400: 55 push %rbp ; | + 401: 48 89 e5 mov %rsp,%rbp ; | prolog + 404: 48 83 ec 30 sub $0x30,%rsp ; | + 408: 31 ff xor %edi,%edi ; arg 0 + 40a: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) ; unsure... write 0 to local area @@@? + 411: c7 45 e8 05 00 00 00 movl $0x5,-0x18(%rbp) ; | field i + 418: c7 45 ec 06 00 00 00 movl $0x6,-0x14(%rbp) ; | fill struct A (local area) field j + 41f: 48 c7 45 f0 07 00 00 00 movq $0x7,-0x10(%rbp) ; | field l + 427: be 01 00 00 00 mov $0x1,%esi ; arg 1 + 42c: ba 02 00 00 00 mov $0x2,%edx ; arg 2 + 431: b9 03 00 00 00 mov $0x3,%ecx ; arg 3 + 436: 41 b8 04 00 00 00 mov $0x4,%r8d ; arg 4 + 43c: 48 8d 45 e8 lea -0x18(%rbp),%rax ; | + 440: 4c 8b 08 mov (%rax),%r9 ; | + 443: 4c 89 0c 24 mov %r9,(%rsp) ; | arg 5 (struct, pushed onto stack, as not enough regs) + 447: 48 8b 40 08 mov 0x8(%rax),%rax ; | + 44b: 48 89 44 24 08 mov %rax,0x8(%rsp) ; | + 450: 41 b9 08 00 00 00 mov $0x8,%r9d ; arg 6 (in reg) + 456: c7 44 24 10 09 00 00 00 movl $0x9,0x10(%rsp) ; arg 7 (pushed) + 45e: b0 00 mov $0x0,%al ; number of used xmm registers (upper bound, req for varargs) + 460: e8 00 00 00 00 callq 465 ; push return addr and call + 465: 31 c0 xor %eax,%eax ; return value + 467: 48 83 c4 30 add $0x30,%rsp ; | + 46b: 5d pop %rbp ; | epilog + 46c: c3 retq ; | + + + ; vim: ft=asm