Что -fverbose-asm пытается сказать на сборке? - PullRequest
2 голосов
/ 20 июня 2020

Я скомпилировал эту функцию:

void print_ints(int len, ...){
    va_list args;
    va_start(args, len);

    for(int i =0; i<len ; i++)
    {
        int val = va_arg(args,int);
        printf("i:%i\tval:%i\n",i,val);
    }

    va_end(args);
}

в эту сборку:

print_ints:
pushq   %rbp    #
    movq    %rsp, %rbp  #,
    subq    $224, %rsp  #,
    movl    %edi, -212(%rbp)    # len, len
    movq    %rsi, -168(%rbp)    #,
    movq    %rdx, -160(%rbp)    #,
    movq    %rcx, -152(%rbp)    #,
    movq    %r8, -144(%rbp) #,
    movq    %r9, -136(%rbp) #,
    testb   %al, %al    #
    je  .L7 #,
    movaps  %xmm0, -128(%rbp)   #,
    ...
.L7:
# a.c:7:    va_start(args, len);
    movl    $8, -208(%rbp)  #, MEM[(struct [1] *)&args].gp_offset
    movl    $48, -204(%rbp) #, MEM[(struct [1] *)&args].fp_offset
    leaq    16(%rbp), %rax  #, tmp100
    movq    %rax, -200(%rbp)    # tmp100, MEM[(struct [1] *)&args].overflow_arg_area
    leaq    -176(%rbp), %rax    #, tmp101
    movq    %rax, -192(%rbp)    # tmp101, MEM[(struct [1] *)&args].reg_save_area
# a.c:9:    for(int i =0; i<len ; i++)
    movl    $0, -180(%rbp)  #, i
# a.c:9:    for(int i =0; i<len ; i++)
    jmp .L3 #
.L6:
# a.c:11:       int val = va_arg(args,int);
    movl    -208(%rbp), %eax    # MEM[(struct  *)&args].gp_offset, D.2882
    cmpl    $47, %eax   #, D.2882
    ja  .L4 #,
# a.c:11:       int val = va_arg(args,int);
    ...

Я знаю, что это похоже на беспорядок, но есть некоторая часть вывода, которая меня интересует . Специально такие строки:

movl    $8, -208(%rbp)  #, MEM[(struct [1] *)&args].gp_offset

Я бы попытался проанализировать это:

  1. MEM[...] -> может представлять всю память в виде массива (адреса в виде индекса )
  2. MEM[(struct[1]*)...] -> может представлять тип, который сам этот тип является членом некоторой неизвестной структуры struct[1]*, а затем дает указатель на тип второго члена этой структуры
  3. MEM[(struct[1]*)&args] -> как только тип данных (длина) указан (struct[1]*), он находится по адресу переменной args, поэтому мы знаем, с чего начать
  4. MEM[(struct[1]*)&args].gp_offset -> Итак у нас есть тип, начальный адрес, который вместе дает нам индекс в глобальной таблице памяти, которая получает «некоторое значение», к которому мы хотим получить доступ, чтобы получить gp_offset?

Мои предположения верный? Какие члены или функции (или что это такое) получают члены ->

gp_offset, fp_offset, overflow_arg_area, reg_save_area, ...

Могу ли я найти их реализацию, чтобы увидеть, что они делают? или они задокументированы во внутренней части компилятора?

...