Компиляция после стадии препроцессора, но до стадии сборки - PullRequest
2 голосов
/ 14 февраля 2012

Представьте, что у меня есть набор макросов в программе (macrotest.c), например:

#include <stdio.h>
#include <stdlib.h>
#define n1 75
#define n2 90
#define mac(x,y) ((x > y) ? (12) : (15))

int main(){

   printf("%d",mac(n1,n2));
   exit(0);
}

Когда вы компилируете в сборку (EM64T), вы получаете следующее:

gcc -S -o macrotest.asm macrotest.c

main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %eax
    movl    $15, %esi   <------ This
    movq    %rax, %rdi
    movl    $0, %eax
    call    printf
    movl    $0, %edi
    call    exit
    .cfi_endproc

Вы можете видеть, что он немедленно преобразует mac (n1, n2) в 15. Однако, когда вы компилируете на этапе предварительной обработки, он просто расширяет макросы:

gcc -E -o macrotest.prp macrotest.c

int main(){

   printf("%d",((75 > 90) ? (12) : (15)));
   exit(0);
}

Есть ли какой-нибудь способ, которым я могу далее сломать код C , не входя в сборку?

1 Ответ

3 голосов
/ 14 февраля 2012

Попробуйте опцию -fdump-tree-all и посмотрите, говорит ли это, что вам нужно?

Это выдает внутреннее представление компилятора.Он не использует код на C (вы не могли его взять и скомпилировать), но он немного похож на C. Если вы хотите понять это больше, прочтите «Single Static Assignment» (SSA).

Если вы хотите продвинуться еще дальше к ассемблеру, добавьте -fdump-rtl-all.Для второй половины процесса GCC переключается из формы SSA (в которой компилятор пытается оптимизировать программу) и использует то, что он называет «Register Transfer Language».Цель этого этапа - оптимизировать использование машинных инструкций низкого уровня.Это еще сложнее понять.Попробуйте прочитать руководство по внутренним компонентам GCC.

...