# #x86-64 #nasm #elf #dwarf
Вопрос:
Я компилирую следующий код с помощью NASM (nasm -g -F dwarf -f elf64 test.asm amp;amp; gcc -g3 test.o).
global main
section .text
main:
%line 1 test.txt
PUSH 1337
%line 2 test.txt
PUSH 1338
%line 3 test.txt
PUSH 1339
%line 8 test.txt
POP RAX
%line 9 test.txt
POP RAX
%line 10 test.txt
POP RAX
RET
Я ожидал бы, что это добавит строки 1, 2, 3, 8, 9 и 10 к карликовым данным, однако, когда я исследую файл (используя КАРЛИКОВЫЙ проводник, readelf или собственный код) Вместо этого я получаю следующие строки:
test.txt 2 0x1130 (PUSH 1337)
test.txt 3 0x1135 (PUSH 1338)
test.txt 4 0x113a (PUSH 1339)
test.txt 9 0x113f (POP RAX)
test.txt 10 0x1140 (POP RAX)
test.txt 11 0x1141 (POP RAX)
test.txt 13 0x1142 (RET)
Каждый номер строки на единицу больше, чем я указал в сборке, и, кроме того, в инструкции ret есть дополнительная строка # 13. Кто-нибудь может объяснить, что здесь происходит, и что я должен сделать, чтобы получить ожидаемый результат?
Ответ №1:
PUSH 1337
находится в строке после строки, которую вы сделали строкой 1. Таким образом, кажется %line
, что устанавливается номер этой строки, и обычный механизм NASM для подсчета номеров строк продолжает работать в обычном режиме. (В отличие от устаревшего GAS .line
, который задает номер строки следующей строки.)
Это RET
2 строки после последней POP RAX
, так что это имеет смысл.
Согласно руководству, полный синтаксис включает необязательный параметр для управления увеличением номера строки; по-видимому mmm
, значение по умолчанию равно 1:
%line nnn[ mmm] filename
Так что, возможно (непроверенный)
%line 1 0 test.txt
NASM -g
предназначен для создания отладочной информации для самого источника asm, а не для номеров строк некоторого исходного файла более высокого уровня, который был скомпилирован в .asm
файл NASM. В руководстве говорится, что он предназначен для использования с макропроцессором (отличным от встроенных макросов NASM), где имело бы смысл увеличивать исходные номера строк.
Но если вы хотите взломать эту функциональность, если 0
это не сработает, я думаю, вы могли бы продолжать сбрасывать %line
перед каждой инструкцией, повторяя один и тот же номер строки для единиц в блоке, которые все пришли из одной и той же исходной строки более высокого уровня.
И используйте число перед тем, которое вы хотите использовать в NASM. Поэтому я думаю, используйте %line 0 test.txt
, если вы хотите, чтобы инструкция в следующей строке отображалась как строка 1 из test.txt , потому что 0 — это число перед 1.
(Предполагается, что NASM поддерживает использование 0 в качестве номера строки и перемотку номера строки, чтобы иметь одну и ту же строку дважды.)
Я не знаю директив NASM, эквивалентных по конструкции директивам GAS .loc
, которые предназначены для генерации отладочной информации для C или другого источника высокого уровня, который скомпилирован в a .s
.
Комментарии:
1. Спасибо. Использование 0 действительно дает правильные номера строк, если строка # не равна 1. Первая строка % вообще не регистрируется, если номер строки равен 1. Независимо от ГАЗА. loc кажется лучшим вариантом, поэтому я попробую это сделать.
2. @Sindre: GAS был разработан как часть набора инструментов, в первую очередь для сборки выходных данных компилятора (особенно из GCC). NASM был разработан в основном для рукописных источников asm. NASM обычно имеет лучшие / более четкие предупреждения и сообщения об ошибках (вероятно, по этой причине).