Использование директивы %line в NASM с карликовым форматом отладки не приводит к ожидаемым номерам строк

# #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 обычно имеет лучшие / более четкие предупреждения и сообщения об ошибках (вероятно, по этой причине).