在 NASM 中使用 dwarf 调试格式的 %line 指令不会产生预期的行号

Usage of %line directive in NASM with dwarf debug format does not result in expected line numbers

我正在使用 NASM (nasm -g -F dwarf -f elf64 test.asm && 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 行添加到 dwarf 数据中,但是当我浏览文件时(使用 DWARF 资源管理器、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。谁能解释一下这是怎么回事,我应该怎么做才能得到预期的结果?

PUSH 1337 在第 行之后 你做的第 1 行。所以看起来 %line 设置了 this 的数量 行,NASM 的正常行号计数机制继续正常运行。 (不像 GAS's deprecated .line 设置 下一个 行的行号。)

RET 是最后一个 POP RAX 之后的 2 行,所以这是有道理的。

According to the manual,完整语法包括一个可选参数来控制行号递增;显然 mmm 默认为 1:

%line nnn[+mmm] filename

所以可能(未经测试)

%line 1+0  test.txt

NASM -g 旨在为 asm 源代码本身制作调试信息,而不是为一些更高级别的源文件的行号被编译成 .asm NASM 文件。该手册说它旨在与宏预处理器(NASM 的内置宏除外)一起使用,其中源代码行号递增是有意义的。

但是如果你想破解那个功能,如果 +0 不起作用,我想你可以在每条指令之前继续重置 %line,重复使用相同的行号在一个全部来自同一更高级别源代码行的块中。

并使用您希望 NASM 使用的号码之前的号码。所以我想如果你希望下一行的指令被报告为test.txt的第1行,我想使用%line 0 test.txt,因为0是1之前的数字。

(假设NASM支持使用0作为行号,并且将行号倒回两次以具有相同的行。)

我不知道 NASM 指令在设计上等同于 GAS 的 .loc,其中 用于为 C 或其他高级生成调试信息编译为 .s.

级的源代码