Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 所有asm标签都将成为可执行文件中的符号_Assembly_Linker_X86_Nasm_Elf - Fatal编程技术网

Assembly 所有asm标签都将成为可执行文件中的符号

Assembly 所有asm标签都将成为可执行文件中的符号,assembly,linker,x86,nasm,elf,Assembly,Linker,X86,Nasm,Elf,当使用nasm组装对象时,我发现所有标签都作为符号包含在生成的.o文件以及最终二进制文件中 这对于我声明的GLOBAL函数入口点和部分开始部分(例如.text部分)来说是有意义的,但是标签仅仅用作循环入口点,并且这些都将出现在输出文件中,这似乎很奇怪。除了泄漏内部实现细节外,它还浪费了符号表中的空间 例如,给定此简短的组装程序: GLOBAL _start _start: xor eax, eax normal_label: xor eax, eax .local_label:

当使用
nasm
组装对象时,我发现所有标签都作为符号包含在生成的
.o
文件以及最终二进制文件中

这对于我声明的
GLOBAL
函数入口点和部分开始部分(例如
.text
部分)来说是有意义的,但是标签仅仅用作循环入口点,并且这些都将出现在输出文件中,这似乎很奇怪。除了泄漏内部实现细节外,它还浪费了符号表中的空间

例如,给定此简短的组装程序:

GLOBAL _start
_start:
    xor eax, eax
normal_label:
    xor eax, eax
.local_label:
    xor eax, eax
    xor edi, edi
    mov eax, 231    ;  exit(0)
    syscall
。。。使用以下方式构建:

nasm -f elf64 label-test.s
ld label-test.o -o label-test
在目标文件和链接的可执行文件中产生
l
(即本地)符号:

objdump --syms label-test.o

label-test.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 label-test.s
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000002 l       .text  0000000000000000 normal_label
0000000000000004 l       .text  0000000000000000 normal_label.local_label
0000000000000000 g       .text  0000000000000000 _start
请注意,
normal_label
和本地标签
local_label
都在符号表中结束。它们最后都会出现在可执行文件的符号表中

我不想将这些符号发送到最终的可执行文件。我能告诉nasm不要包括它们吗?我可以将一些选项传递给
ld
,例如
--剥离所有
,这将删除这些符号,还将删除可执行文件中的所有其他符号。这使它变得非常困难:它消除了我真正想要保留的用于可读堆栈跟踪、调试等的符号


正如彼得·科尔德斯(Peter Cordes)所提到的那样,FWIW的yasm不存在完全相同的问题。以与上述完全相同的方式构建elf64
.o
文件(但用
yasm
替换
nasm
),我们得到:

objdump --syms label-test-yasm.o 

label-test-yasm.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 label-test.s
0000000000000004 l       .text  0000000000000000 
0000000000000002 l       .text  0000000000000000 
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g       .text  0000000000000000 _start

全局
\u start
标签仍然包括在内,但其他两个标签没有命名-尽管它们仍然存在,它们是偏移量4和2处的未命名符号(上面列表中的第2行和第3行)。这通过添加更多标签得到了证实-产生了更多未命名的符号。

据我所知,这只是nasm中的一个限制。例如,请参见海报中存在大致相同的问题(虽然是32位ELF而不是64位ELF),除了使用剥离工具之外,没有提供任何解决方案

在我的例子中,似乎剥离对象文件如下:

strip --discard-all label-test.o 
应该可以做到这一点。尽管有
--discard all
选项的名称,但它只删除本地符号,而不删除全局符号。以下是删除文件之前的符号表:

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 label-test.s
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000002 l       .text  0000000000000000 normal_label
0000000000000004 l       .text  0000000000000000 normal_label.local_label
0000000000000000 g       .text  0000000000000000 _start
及之后:

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 label-test.s
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g       .text  0000000000000000 _start
特别要注意的是,它足够聪明,可以将
.text
节符号单独保留,即使它是本地的。当然,此条带选项不能真正区分无用的(循环标签)和潜在有用的符号,例如本地函数入口点,它们是使用各种工具提供正确堆栈跟踪所必需的

如果您想更聪明一些,可以使用
--wildcard
--strip symbol
选项选择性地仅剥离asm本地标签(即以
开头的标签),以选择性地仅剥离嵌入
的标签


如果有人潜伏在那里,我仍然在寻找更好的答案。

据我所知,这只是nasm中的一个限制。例如,请参见海报中存在的大致相同的问题(尽管是32位ELF而不是64位ELF),除了使用剥离工具之外,没有提供任何解决方案

在我的例子中,似乎剥离对象文件如下:

strip --discard-all label-test.o 
应该可以做到这一点。尽管有
--discard all
选项的名称,但它只删除本地符号,而不删除全局符号。以下是删除文件之前的符号表:

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 label-test.s
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000002 l       .text  0000000000000000 normal_label
0000000000000004 l       .text  0000000000000000 normal_label.local_label
0000000000000000 g       .text  0000000000000000 _start
及之后:

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 label-test.s
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g       .text  0000000000000000 _start
特别要注意的是,它足够聪明,可以将
.text
节符号单独保留,即使它是本地的。当然,此条带选项不能真正区分无用的(循环标签)和潜在有用的符号,例如本地函数入口点,它们是使用各种工具提供正确堆栈跟踪所必需的

如果您想更聪明一些,可以使用
--wildcard
--strip symbol
选项选择性地仅剥离asm本地标签(即以
开头的标签),以选择性地仅剥离嵌入
的标签


如果有人潜伏在那里,我仍然在寻找更好的答案。

有点晚,但我遇到了这个问题,并为nasm 2.15编写了一个修补程序来解决这个问题。它添加了一个名为-discard labels的命令行开关。您可以在这里找到它:

有点晚,但我遇到了这个问题,并为nasm 2.15编写了一个修补程序来解决这个问题。它添加了一个命令行开关,名为-discard labels和名为-discard labels的行开关。您可以在这里获得它:

yasm默认情况下不会这样做。(如果您使用
-gdwarf2
,它会这样做)嗯,是的。也许这有点纳什怪癖。我把它添加到了问题的底部。你提到了
-g
的东西,我突然想到这些都是为了调试而添加的,但值得注意的是
-ld
命令上的
-strip debug
并没有删除它们(或任何符号)在nasm构建的二进制文件上。这次我更努力地搜索了一下,看起来它可能只是一个。对,我的意思是我假设有某种方法可以摆脱
标签,留下非
标签。也就是说,我假设nasm会有某种方法来完成yasm所做的事情(因为它显然很有用),但没有费心去看,因为我通常只使用yasm。对yasm进行更正,它会将条目添加到符号表中,但它们是“未命名的”。上面添加的详细信息。默认情况下,yasm不会这样做。(如果使用
-gdwarf2
,它会这样做)嗯,是的。也许这有点纳什怪癖。我把它添加到了问题的底部。你提到了
-g
的东西,我突然想到这些都是为了调试而添加的,但值得注意的是
-ld
命令上的
-strip debug
并没有删除它们(或任何符号)在nasm构建的二进制文件上。我在谷歌上搜索了这个