Я ни в коем случае не эксперт по внутренним компонентам GCC, но я сделаю это.К сожалению, большая часть информации о распределении и распределении регистров GCC устарела (ссылаясь на файлы, такие как local-alloc.c
, которые больше не существуют).
Я смотрю на исходный код gcc-4.5-20110825
.
В Внутренние компоненты компилятора GNU C упоминается, что исходный код функции генерируется expand_function_start
в gcc/function.c
.Там мы находим следующее для обработки параметров:
4462 /* Initialize rtx for parameters and local variables.
4463 In some cases this requires emitting insns. */
4464 assign_parms (subr);
В assign_parms
код, который обрабатывает каждый аргумент, хранится в следующем:
3207 if (assign_parm_setup_block_p (&data))
3208 assign_parm_setup_block (&all, parm, &data);
3209 else if (data.passed_pointer || use_register_for_decl (parm))
3210 assign_parm_setup_reg (&all, parm, &data);
3211 else
3212 assign_parm_setup_stack (&all, parm, &data);
assign_parm_setup_block_p
обрабатывает агрегированные данныетипы и не применимы в этом случае и поскольку данные не передаются в качестве указателя, GCC проверяет use_register_for_decl
.
Здесь соответствующая часть:
1972 if (optimize)
1973 return true;
1974
1975 if (!DECL_REGISTER (decl))
1976 return false;
DECL_REGISTER
проверяет, была ли переменная объявлена с ключевым словом register
.И теперь у нас есть ответ: большинство параметров живут в стеке, когда оптимизация не включена, и затем обрабатываются assign_parm_setup_stack
.Маршрут, пройденный через исходный код до того, как он закончится разливом значения, немного сложнее для аргументов указателя, но может быть отслежен в том же файле, если вам интересно.
Почему GCC выдает все аргументы и локальныепеременные с отключенной оптимизацией?Чтобы помочь отладке.Рассмотрим эту простую функцию:
1 extern int bar(int);
2 int foo(int a) {
3 int b = bar(a | 1);
4 b += 42;
5 return b;
6 }
Скомпилировано с gcc -O1 -c
, на моем компьютере это генерирует следующее:
0: 48 83 ec 08 sub $0x8,%rsp
4: 83 cf 01 or $0x1,%edi
7: e8 00 00 00 00 callq c <foo+0xc>
c: 83 c0 2a add $0x2a,%eax
f: 48 83 c4 08 add $0x8,%rsp
13: c3 retq
Это нормально, за исключением случаев, когда вы разбиваете строку 5 и пытаетесь распечататьзначение a, вы получите
(gdb) print a
$1 = <value optimized out>
, так как аргумент перезаписывается, так как он не используется после вызова bar
.