System V AMD64 ABI порядок с плавающей запятой - PullRequest
0 голосов
/ 23 октября 2018

Я скомпилировал вызов printf с различными типами аргументов.
Вот код + сгенерированный asm:

int main(int argc, char const *argv[]){
    //   0: 55                      push   rbp
    //   1: 48 89 e5                mov    rbp,rsp
    //   4: 48 83 ec 20             sub    rsp,0x20
    //   8: 89 7d fc                mov    DWORD PTR [rbp-0x4],edi
    //   b: 48 89 75 f0             mov    QWORD PTR [rbp-0x10],rsi
    printf("%s %f %d %f\n", "aye u gonna get some", 133.7f, 420, 69.f);
    //   f: f2 0f 10 05 00 00 00 00 movsd  xmm0,QWORD PTR [rip+0x0]        # 17 <main+0x17> 13: R_X86_64_PC32   .rodata+0x2c    69
    //  17: 48 8b 05 00 00 00 00    mov    rax,QWORD PTR [rip+0x0]        # 1e <main+0x1e>  1a: R_X86_64_PC32   .rodata+0x34    133.7
    //  1e: 66 0f 28 c8             movapd xmm1,xmm0
    //  22: ba a4 01 00 00          mov    edx,0x1a4 (420)
    //  27: 48 89 45 e8             mov    QWORD PTR [rbp-0x18],rax
    //  2b: f2 0f 10 45 e8          movsd  xmm0,QWORD PTR [rbp-0x18]
    //  30: 48 8d 35 00 00 00 00    lea    rsi,[rip+0x0]        # 37 <main+0x37>    33: R_X86_64_PC32   .rodata-0x4  "aye u wanna get some"
    //  37: 48 8d 3d 00 00 00 00    lea    rdi,[rip+0x0]        # 3e <main+0x3e>    3a: R_X86_64_PC32   .rodata+0x18 "%s %f %d %f\n"
    //  3e: b8 02 00 00 00          mov    eax,0x2
    //  43: e8 00 00 00 00          call   48 <main+0x48>   44: R_X86_64_PLT32  printf-0x4
    return 0;
    //  48: b8 00 00 00 00          mov    eax,0x0
    //  4d: c9                      leave  
    //  4e: c3                      ret    
}

Большинство вещей здесь имеют смысл для меня.На самом деле все здесь имеет некоторый уровень смысла для меня.
"%s %f %d %f\n" -> rdi
"aye u gonna get some" -> rsi
133.7 -> xmm0
420 -> rdx
69 -> xmm1
2 -> rax (чтобы указать, что есть 2 аргумента с плавающей запятой)

Теперь я не понимаю, как printf (или любая другая функция varargs) будетвыяснить положение этих аргументов с плавающей запятой среди других.

Это также не может быть магией компилятора, так как он динамически связан.
Так что единственное, о чем я могу думать, это, может быть, это просто внутренняя часть va_arg, и как, когда вы предоставляете тип, если это с плавающей точкой,он должен получить из xmms (или стека), а не иначе.

Это правильно?Если нет, то как другая сторона узнает, где их взять?Заранее спасибо.

1 Ответ

0 голосов
/ 23 октября 2018

Для printf строка формата указывает тип оставшихся аргументов.

Реализация va_arg знает тип, поскольку он является аргументом va_arg, и из типов можно вывести правильный регистр.

...