测试代码
void test_arg(int a, float b, int c, long double d, double e)
{
int a1 = a;
float b1 = b;
int c1 = c;
long double d1 = d;
double e1 = e;
}
void test_varg(int a, ...)
{
va_list vl;
va_start(vl, a);
int a1 = a;
float b1 = (float)va_arg(vl, double);
int c1 = va_arg(vl, int);
long double d1 = va_arg(vl, long double);
double e1 = va_arg(vl, double);
va_end(vl);
}
int main (void)
{
int a = 1;
float b = 2.0f;
int c = 3;
long double d = 4.0;
double e = 5.0;
test_arg(a, b, c, d, e);
test_varg(a, b, c, d, e);
return 0;
}
反汇编(gcc2.8.5
gcc xxx.c -g -O0
)
00000000004004f0 <_Z8test_argified>:
#include <stdio.h>
#include <stdarg.h>
void test_arg(int a, float b, int c, long double d, double e)
{
4004f0: 55 push %rbp
4004f1: 48 89 e5 mov %rsp,%rbp
4004f4: 89 7d cc mov %edi,-0x34(%rbp)
4004f7: f3 0f 11 45 c8 movss %xmm0,-0x38(%rbp)
4004fc: 89 75 c4 mov %esi,-0x3c(%rbp)
4004ff: f2 0f 11 4d b8 movsd %xmm1,-0x48(%rbp)
int a1 = a;
400504: 8b 45 cc mov -0x34(%rbp),%eax
400507: 89 45 fc mov %eax,-0x4(%rbp)
float b1 = b;
40050a: 8b 45 c8 mov -0x38(%rbp),%eax
40050d: 89 45 f8 mov %eax,-0x8(%rbp)
int c1 = c;
400510: 8b 45 c4 mov -0x3c(%rbp),%eax
400513: 89 45 f4 mov %eax,-0xc(%rbp)
long double d1 = d;
400516: 48 8b 45 10 mov 0x10(%rbp),%rax
40051a: 8b 55 18 mov 0x18(%rbp),%edx
40051d: 48 89 45 e0 mov %rax,-0x20(%rbp)
400521: 89 55 e8 mov %edx,-0x18(%rbp)
double e1 = e;
400524: 48 8b 45 b8 mov -0x48(%rbp),%rax
400528: 48 89 45 d8 mov %rax,-0x28(%rbp)
}
40052c: 5d pop %rbp
40052d: c3 retq
000000000040052e <_Z9test_vargiz>:
void test_varg(int a, ...)
{
40052e: 55 push %rbp
40052f: 48 89 e5 mov %rsp,%rbp
400532: 48 83 ec 7c sub $0x7c,%rsp
400536: 48 89 b5 58 ff ff ff mov %rsi,-0xa8(%rbp)
40053d: 48 89 95 60 ff ff ff mov %rdx,-0xa0(%rbp)
400544: 48 89 8d 68 ff ff ff mov %rcx,-0x98(%rbp)
40054b: 4c 89 85 70 ff ff ff mov %r8,-0x90(%rbp)
400552: 4c 89 8d 78 ff ff ff mov %r9,-0x88(%rbp)
400559: 84 c0 test %al,%al
40055b: 74 20 je 40057d <_Z9test_vargiz+0x4f>
40055d: 0f 29 45 80 movaps %xmm0,-0x80(%rbp)
400561: 0f 29 4d 90 movaps %xmm1,-0x70(%rbp)
400565: 0f 29 55 a0 movaps %xmm2,-0x60(%rbp)
400569: 0f 29 5d b0 movaps %xmm3,-0x50(%rbp)
40056d: 0f 29 65 c0 movaps %xmm4,-0x40(%rbp)
400571: 0f 29 6d d0 movaps %xmm5,-0x30(%rbp)
400575: 0f 29 75 e0 movaps %xmm6,-0x20(%rbp)
400579: 0f 29 7d f0 movaps %xmm7,-0x10(%rbp)
40057d: 89 bd 0c ff ff ff mov %edi,-0xf4(%rbp)
va_list vl;
va_start(vl, a);
400583: c7 85 10 ff ff ff 08 movl $0x8,-0xf0(%rbp)
40058a: 00 00 00
40058d: c7 85 14 ff ff ff 30 movl $0x30,-0xec(%rbp)
400594: 00 00 00
400597: 48 8d 45 10 lea 0x10(%rbp),%rax
40059b: 48 89 85 18 ff ff ff mov %rax,-0xe8(%rbp)
4005a2: 48 8d 85 50 ff ff ff lea -0xb0(%rbp),%rax
4005a9: 48 89 85 20 ff ff ff mov %rax,-0xe0(%rbp)
int a1 = a;
4005b0: 8b 85 0c ff ff ff mov -0xf4(%rbp),%eax
4005b6: 89 85 4c ff ff ff mov %eax,-0xb4(%rbp)
float b1 = (float)va_arg(vl, double);
4005bc: 8b 85 14 ff ff ff mov -0xec(%rbp),%eax
4005c2: 3d b0 00 00 00 cmp $0xb0,%eax
4005c7: 73 23 jae 4005ec <_Z9test_vargiz+0xbe>
4005c9: 48 8b 95 20 ff ff ff mov -0xe0(%rbp),%rdx
4005d0: 8b 85 14 ff ff ff mov -0xec(%rbp),%eax
4005d6: 89 c0 mov %eax,%eax
4005d8: 48 01 d0 add %rdx,%rax
4005db: 8b 95 14 ff ff ff mov -0xec(%rbp),%edx
4005e1: 83 c2 10 add $0x10,%edx
4005e4: 89 95 14 ff ff ff mov %edx,-0xec(%rbp)
4005ea: eb 15 jmp 400601 <_Z9test_vargiz+0xd3>
4005ec: 48 8b 95 18 ff ff ff mov -0xe8(%rbp),%rdx
4005f3: 48 89 d0 mov %rdx,%rax
4005f6: 48 83 c2 08 add $0x8,%rdx
4005fa: 48 89 95 18 ff ff ff mov %rdx,-0xe8(%rbp)
400601: f2 0f 10 00 movsd (%rax),%xmm0
400605: 66 0f 14 c0 unpcklpd %xmm0,%xmm0
400609: 66 0f 5a c8 cvtpd2ps %xmm0,%xmm1
40060d: f3 0f 11 8d 48 ff ff movss %xmm1,-0xb8(%rbp)
400614: ff
int c1 = va_arg(vl, int);
400615: 8b 85 10 ff ff ff mov -0xf0(%rbp),%eax
40061b: 83 f8 30 cmp $0x30,%eax
40061e: 73 23 jae 400643 <_Z9test_vargiz+0x115>
400620: 48 8b 95 20 ff ff ff mov -0xe0(%rbp),%rdx
400627: 8b 85 10 ff ff ff mov -0xf0(%rbp),%eax
40062d: 89 c0 mov %eax,%eax
40062f: 48 01 d0 add %rdx,%rax
400632: 8b 95 10 ff ff ff mov -0xf0(%rbp),%edx
400638: 83 c2 08 add $0x8,%edx
40063b: 89 95 10 ff ff ff mov %edx,-0xf0(%rbp)
400641: eb 15 jmp 400658 <_Z9test_vargiz+0x12a>
400643: 48 8b 95 18 ff ff ff mov -0xe8(%rbp),%rdx
40064a: 48 89 d0 mov %rdx,%rax
40064d: 48 83 c2 08 add $0x8,%rdx
400651: 48 89 95 18 ff ff ff mov %rdx,-0xe8(%rbp)
400658: 8b 00 mov (%rax),%eax
40065a: 89 85 44 ff ff ff mov %eax,-0xbc(%rbp)
long double d1 = va_arg(vl, long double);
400660: 48 8b 85 18 ff ff ff mov -0xe8(%rbp),%rax
400667: 48 83 c0 0f add $0xf,%rax
40066b: 48 83 e0 f0 and $0xfffffffffffffff0,%rax
40066f: 48 89 c2 mov %rax,%rdx
400672: 48 83 c0 10 add $0x10,%rax
400676: 48 89 85 18 ff ff ff mov %rax,-0xe8(%rbp)
40067d: 48 8b 02 mov (%rdx),%rax
400680: 8b 52 08 mov 0x8(%rdx),%edx
400683: 48 89 85 30 ff ff ff mov %rax,-0xd0(%rbp)
40068a: 89 95 38 ff ff ff mov %edx,-0xc8(%rbp)
double e1 = va_arg(vl, double);
400690: 8b 85 14 ff ff ff mov -0xec(%rbp),%eax
400696: 3d b0 00 00 00 cmp $0xb0,%eax
40069b: 73 23 jae 4006c0 <_Z9test_vargiz+0x192>
40069d: 48 8b 95 20 ff ff ff mov -0xe0(%rbp),%rdx
4006a4: 8b 85 14 ff ff ff mov -0xec(%rbp),%eax
4006aa: 89 c0 mov %eax,%eax
4006ac: 48 01 d0 add %rdx,%rax
4006af: 8b 95 14 ff ff ff mov -0xec(%rbp),%edx
4006b5: 83 c2 10 add $0x10,%edx
4006b8: 89 95 14 ff ff ff mov %edx,-0xec(%rbp)
4006be: eb 15 jmp 4006d5 <_Z9test_vargiz+0x1a7>
4006c0: 48 8b 95 18 ff ff ff mov -0xe8(%rbp),%rdx
4006c7: 48 89 d0 mov %rdx,%rax
4006ca: 48 83 c2 08 add $0x8,%rdx
4006ce: 48 89 95 18 ff ff ff mov %rdx,-0xe8(%rbp)
4006d5: 48 8b 00 mov (%rax),%rax
4006d8: 48 89 85 28 ff ff ff mov %rax,-0xd8(%rbp)
va_end(vl);
}
4006df: c9 leaveq
4006e0: c3 retq
00000000004006e1 <main>:
int main (void)
{
4006e1: 55 push %rbp
4006e2: 48 89 e5 mov %rsp,%rbp
4006e5: 48 83 ec 50 sub $0x50,%rsp
int a = 1;
4006e9: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%rbp)
float b = 2.0f;
4006f0: 8b 05 3a 01 00 00 mov 0x13a(%rip),%eax # 400830 <__dso_handle+0x8>
4006f6: 89 45 f8 mov %eax,-0x8(%rbp)
int c = 3;
4006f9: c7 45 f4 03 00 00 00 movl $0x3,-0xc(%rbp)
long double d = 4.0;
400700: 48 b8 00 00 00 00 00 movabs $0x8000000000000000,%rax
400707: 00 00 80
40070a: ba 01 40 00 00 mov $0x4001,%edx
40070f: 48 89 45 e0 mov %rax,-0x20(%rbp)
400713: 89 55 e8 mov %edx,-0x18(%rbp)
double e = 5.0;
400716: 48 b8 00 00 00 00 00 movabs $0x4014000000000000,%rax
40071d: 00 14 40
400720: 48 89 45 d8 mov %rax,-0x28(%rbp)
test_arg(a, b, c, d, e);
400724: 48 8b 75 d8 mov -0x28(%rbp),%rsi
400728: 44 8b 45 f4 mov -0xc(%rbp),%r8d
40072c: 8b 4d f8 mov -0x8(%rbp),%ecx
40072f: 8b 7d fc mov -0x4(%rbp),%edi
400732: 48 8b 45 e0 mov -0x20(%rbp),%rax
400736: 8b 55 e8 mov -0x18(%rbp),%edx
400739: 48 89 04 24 mov %rax,(%rsp)
40073d: 89 54 24 08 mov %edx,0x8(%rsp)
400741: 48 89 75 c8 mov %rsi,-0x38(%rbp)
400745: f2 0f 10 4d c8 movsd -0x38(%rbp),%xmm1
40074a: 44 89 c6 mov %r8d,%esi
40074d: 89 4d c8 mov %ecx,-0x38(%rbp)
400750: f3 0f 10 45 c8 movss -0x38(%rbp),%xmm0
400755: e8 96 fd ff ff callq 4004f0 <_Z8test_argified>
test_varg(a, b, c, d, e);
40075a: f3 0f 10 45 f8 movss -0x8(%rbp),%xmm0
40075f: 0f 5a c0 cvtps2pd %xmm0,%xmm0
400762: 48 8b 4d d8 mov -0x28(%rbp),%rcx
400766: 8b 75 f4 mov -0xc(%rbp),%esi
400769: 8b 7d fc mov -0x4(%rbp),%edi
40076c: 48 8b 45 e0 mov -0x20(%rbp),%rax
400770: 8b 55 e8 mov -0x18(%rbp),%edx
400773: 48 89 04 24 mov %rax,(%rsp)
400777: 89 54 24 08 mov %edx,0x8(%rsp)
40077b: 48 89 4d c8 mov %rcx,-0x38(%rbp)
40077f: f2 0f 10 4d c8 movsd -0x38(%rbp),%xmm1
400784: b8 02 00 00 00 mov $0x2,%eax
400789: e8 a0 fd ff ff callq 40052e <_Z9test_vargiz>
return 0;
40078e: b8 00 00 00 00 mov $0x0,%eax
}
结论
- If the class is MEMORY, pass the argument on the stack.
- If the class is INTEGER or POINTER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used13.
- If the class is SSE, the next available vector register is used, the registers are taken in the order from %xmm0 to %xmm7.
- If the class is SSEUP, the eightbyte is passed in the next available eightbyte chunk of the last used vector register.
-
If the class is X87, X87UP or COMPLEX_X87, it is passed in memory.
int a edi edi float b xmm0 xmm0 int c rsi rcx long double d 内存 内存 double e xmm1 xmm1