为什么 GNU `ld` 使用等效源与 NASM 和 GAS `.o` 文件有不同的输出?

问题描述 投票:0回答:1

在对 tiny ELF 可执行文件进行一些受许多有趣 文章启发的实验时,我注意到 GNU 的

ld
在使用
nasm
生成的
.o
目标文件或使用(GNU)
as
生成的一个,都使用(我认为是 1)等效的汇编源。

¹:它们的目标文件仅在非代码部分有所不同,并且如果我strip --strip-section-headers *.o,则“按位相同”,所以我相信这是一个公平的假设。

NASM

(v2.16.1): ; tiny-nasm.asm SECTION .text GLOBAL _start _start: mov eax, 60 ; Select the _exit syscall (60 in Linux ABI) mov edi, 42 ; Set the exit code argument for _exit syscall ; Perform the selected syscall

气体

(v2.42): # tiny-gas.S .SECTION .text .GLOBL _start _start: mov $60, %eax # Select the _exit syscall (60 in Linux ABI) mov $42, %edi # Set the exit code argument for _exit syscall # Perform the selected syscall

nasm -f elf64 tiny-nasm.asm && ld -no-pie -z noseparate-code tiny-nasm.o -o tiny-nasm.bin
as tiny-gas.S -o tiny-gas.o && ld -no-pie -z noseparate-code tiny-gas.o  -o tiny-gas.bin
strip --strip-section-headers *.bin
wc -c *.bin
diff -u <(readelf -Wa tiny-nasm.bin) <(readelf -Wa tiny-gas.bin)
132 tiny-gas.bin
140 tiny-nasm.bin
272 total

--- /dev/fd/63  2024-11-26 02:56:40.248293325 -0300
+++ /dev/fd/62  2024-11-26 02:56:40.248293325 -0300
@@ -8,7 +8,7 @@
   Type:                              EXEC (Executable file)
   Machine:                           Advanced Micro Devices X86-64
   Version:                           0x1
-  Entry point address:               0x400080
+  Entry point address:               0x400078
   Start of program headers:          64 (bytes into file)
   Start of section headers:          0 (bytes into file)
   Flags:                             0x0
@@ -25,7 +25,7 @@
 
 Program Headers:
   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
-  LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x00008c 0x00008c R E 0x1000
+  LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x000084 0x000084 R E 0x1000
 
 There is no dynamic section in this file.
两个二进制文件的工作方式相同且符合预期,它们的
唯一

区别是ld选择的入口点地址偏移量,它占文件大小,

as
小8个字节。

为什么
    ld
  • 会出现这种差异?
    
    
  • 由于参数相同,我假设解释位于(删除的)部分,为简洁起见,我在此处省略了这些部分,但如果需要,可以将其包括在内。但是这些部分中的什么可以触发
ld

选择的不同入口点地址?

如果相关:Ubuntu 24.04、Linux 桌面 6.8.0-48 x86_64、binutils 2.42、AMD Ryzen 5 5700G

linux nasm ld elf
1个回答
0
投票
,ELF

section .text的默认属性是 section .text progbits alloc exe nowrite align=16

显然气体的对齐程度较低,低于或等于 8,所以这就是您观察到差异的方式。解决方案是在 
align=1

指令中指定

section

 属性,如下所示:
section .text align=1


© www.soinside.com 2019 - 2024. All rights reserved.