使用每个标签地址,.o 文件的总大小会增加 24 个字节(加上 8 个字节(总共 32 个字节))

Hel*_*ine 0 assembly executable x86-64 object-files fasm

在我的 FASM 项目(对象)中,我尝试创建一个跳转表并用于dq每个跳转地址,但有一个问题!
对于每个dq .jmp1(跳转地址定义),.jmp1我的最终 .o 文件的总大小将添加 24 个字节(加上地址的 8 个字节(总共 32 个字节))!
那额外的 24 个字节是什么?有什么办法可以避免吗?这种情况仅发生在目标文件中,而不发生在可执行文件中!

它定义了 32 个字节,而不是每个跳转地址 8 个字节!问题是什么?

format ELF64

section '.text'

func:
        lea     rax, [8*rax+.jmp_table]

 .jmp1:

 .jmp_table:
        dq .jmp1 ; 8 bytes + 24 bytes !!! (to .o total size)
        dq .jmp1 ; 8 bytes + 24 bytes !!! (to .o total size)   
Run Code Online (Sandbox Code Playgroud)

但是当我创建一个可执行文件时,每个文件dq只需要 8 个字节(这是我所期望的)......

format ELF64 EXECUTABLE

segment readable executable

func:
        lea     rax, [8*rax+.jmp_table]

 .jmp1:

 .jmp_table:
        dq .jmp1 ; 8-BYTE, no extra 24 bytes to .o total size
        dq .jmp1 ; 8-BYTE, no extra 24 bytes to .o total size
Run Code Online (Sandbox Code Playgroud)

Nat*_*dge 9

请记住,.o文件不仅仅是您组装的代码和数据的平面图像;它也是您所组装的代码和数据的平面图像。它还包含元数据,例如重定位。

由于dq .jmp1引用的符号的绝对地址只有在链接后才能知道,因此它需要重定位条目。上面的链接显示 x86-64 上的 ELF 使用Elf64_Rela重定位条目,该条目为 24 字节。因此,8 字节的实际数据加上 24 字节的元数据,正好导致文件大小增加了 32 字节。(在其他情况下可能或多或少,例如可能是由于对齐要求的填充。)

链接完成后,重定位元数据不会包含在可执行文件中,因此可执行文件的大小仅增加实际数据的大小。

所以你所看到的情况是完全正常的,没有什么可以避免的。事实上,跳转表条目将占用程序存储器中的 8 个字节,并且您的算术 lea rax, [8*rax+.jmp_table]仍然正确。