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

Each label address used, adds 24 bytes more (plus 8 bytes (totalling 32 bytes)) to the .o file's total size

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

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

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)   

但是当我创建一个 executable 时,每个 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

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

由于 dq .jmp1 引用了一个符号,其绝对地址在 linking 之后才知道,因此它需要一个重定位条目。上面的 link 表明 x86-64 上的 ELF 使用 Elf64_Rela 重定位条目,它们是 24 字节。因此,实际数据的 8 个字节加上 24 个字节的元数据,恰好说明了文件大小增加 32 个字节。 (在其他情况下可能或多或少,例如可能是由于对齐要求的填充。)

linking 完成后,重定位元数据不包含在 executable 中,因此 executable 大小仅增加了实际数据的大小。

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