Je reçois les mêmes résultats que sur ma machine (Mac OS X, donc AMD/Linux ABI). Les paramètres à virgule flottante sont transmis dans les registres XMM et les paramètres entiers dans les registres d'entiers. Lorsque printf
les attrape en utilisant va_arg
, il tire à partir de XMM lorsqu'il voit le format %f
, et des autres registres lorsqu'il voit %lld
. Voici le démontage de votre programme compilé (-O0
) sur ma machine:
1 _main:
2 pushq %rbp
3 movq %rsp,%rbp
4 subq $0x20,%rsp
5 movq $0x3f1e68a0d349be90,%rax
6 move %rax,0xf8(%rbp)
7 movq $0x00000000,0xf0(%rbp)
8 movq 0xf0(%rbp),%rdx
9 movq 0xf0(%rbp),%rsi
10 movsd 0xf8(%rbp),%xmm0
11 movq 0xf8(%rbp),%rax
12 movapd %xmm0,%xmm1
13 movq %rax,0xe8(%rbp)
14 movsd 0xe8(%rbp),%xmm0
15 lea 0x0000001d(%rip),%rdi
16 movl $0x00000002,%eax
17 callq 0x100000f22 ; symbol stub for: _printf
18 movl $0x00000000,%eax
19 leave
20 ret
Là, vous pouvez voir ce qui se passe - la chaîne de format est passé dans %rdi
, vos paramètres sont passés (dans l'ordre) dans: %xmm0
, %xmm1
, %rsi
et %rdx
. Lorsque printf
les obtient, il les affiche dans un ordre différent (l'ordre spécifié dans votre chaîne de format). Cela signifie qu'il les fait apparaître: %rsi
, %xmm0
, %rdx
, %xmm1
, donnant les résultats que vous voyez. Le 2
dans %eax
est d'indiquer le nombre d'arguments à virgule flottante passés.
Edit:
est ici une version optimisée - dans ce cas, le code plus court pourrait être plus facile à comprendre. L'explication est la même que ci-dessus, mais avec un bruit un peu moins chaud. La valeur en virgule flottante est chargé par le movsd
en ligne 4.
1 _main:
2 pushq %rbp
3 movq %rsp,%rbp
4 movsd 0x00000038(%rip),%xmm0
5 xorl %edx,%edx
6 xorl %esi,%esi
7 movaps %xmm0,%xmm1
8 leaq 0x00000018(%rip),%rdi
9 movb $0x02,%al
10 callq 0x100000f18 ; symbol stub for: _printf
11 xorl %eax,%eax
12 leave
13 ret
'il déclenche un comportement non spécifié' ... nuff dit: P – pmg
@pmg: Le comportement est * indéfini *, non non spécifié (7.19.6.1.9). Il existe une différence. –
@Martin: Il ne peut pas être expliqué par la norme, mais il peut encore être expliqué; le comportement est indéfini, non non déterministe. C'est une vraie question, mais pas sur le langage C. –