Ответ 1
.loc
Как упоминалось Ferruccio .loc
, это директива отладки, и она появляется только в GCC 4.8.2, если вы сообщите компилятору генерировать отладочную информацию с помощью -ggdb
.
.loc
документируется на https://sourceware.org/binutils/docs-2.18/as/LNS-directives.html#LNS-directives, а точный результат зависит от формата данных отладки (DWARF2 и т.д.).
Другими являются метки.
.L префикс
GCC использует .L
для локальных меток.
GAS не будет генерировать какие-либо символы на скомпилированном выходе по умолчанию, как описано в: https://sourceware.org/binutils/docs-2.18/as/Symbol-Names.html
Локальный символ - это любой символ, начинающийся с определенных префиксов локальных меток. По умолчанию префикс локальной метки - `.L 'для систем ELF
Локальные символы определяются и используются внутри ассемблера, но обычно они не сохраняются в объектных файлах. Таким образом, они не видны при отладке. Вы можете использовать опцию -L (см. "Включение локальных символов: -L" ), чтобы сохранить локальные символы в объектных файлах.
Итак, если вы скомпилируете с помощью: as -c a.S
, nm a.o
не отображает эти метки вообще.
Это имеет смысл только потому, что вы не можете генерировать такие метки из программы C.
Есть также опции, которые управляют им, как:
-
man as
--keep-locals
-
man ld
--discard-all
Это, по-видимому, является специальным соглашением по связям с GCC, а не частью ELF ABI или NASM.
Кроме того, как NASM, так и GAS используют соглашение, в котором метки, начинающиеся с периода (но не .L
в GAS), генерируют локальные символы: http://www.nasm.us/doc/nasmdoc3.html#section-3.9 все еще присутствуют на выходе.
Суффиксы
Суффиксы, о которых вы упоминаете, как представляется, связаны с отладкой, поскольку они определены в gcc/dwarf2out.c в GCC 4.8.2 и DWARF2 является основным форматом информации для отладки для ELF:
#define FUNC_BEGIN_LABEL "LFB"
#define FUNC_END_LABEL "LFE"
#define BLOCK_BEGIN_LABEL "LBB"
#define BLOCK_END_LABEL "LBE"
ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num);
Из моих экспериментов некоторые из них генерируются только с помощью gcc -g
, другие даже без g
.
Как только у нас есть эти имена определений, легко сгенерировать C-код, который генерирует их, чтобы увидеть, что они означают:
-
LFB
иLFE
создаются в начале и в конце функций -
LBB
иLBE
были сгенерированы следующим кодом сgcc -g
во внутренних областях функциональных блоков:#include <stdio.h> int main() { int i = 0; { int i = 1; printf("%d\n", i); } return 0; }
-
LVL
: TODO Я не мог легко понять это. Нам нужно будет интерпретировать источник еще немного.