【问题标题】:Assemble and run i386 asm program on x86-64 Linux with as and ld使用 as 和 ld 在 x86-64 Linux 上组装并运行 i386 asm 程序
【发布时间】:2018-11-02 11:38:08
【问题描述】:

所以我是新尝试 asm,我想编译一个小程序,它只使用 i386 指令而不是 x86-64 指令退出。我有一个 x86-64 Ubuntu,它可以完美地编译和运行 x86-64,但我不知道如何在同一台 x86-64 机器上组装和链接 i386 版本(我已经安装了 i386 compat)。

我知道已经回答了类似的问题,但是他们都没有使用 asld 来解决问题,所以我不知道如何将这些解决方案转化为我的问题。

对于 x86-64,我使用 asld,如下所示:

#       Assemble: as exit.s -o exit.o
#        Linking: ld exit.o -o exit

x86-32版本的程序:

.section .data
.section .text
.globl _start
_start:
    movl $1, %eax
    movl $0, %ebx
    int $0x80

现在.. 我一直在寻找如何做到这一点,并在 as 和 ld 中找到了 --32ld 中的 -m {arg},但每次我编译它时不会出现拱形错误,它会给我“文件格式错误”错误。

我试过像这样用 elf_i386 和 i386linux 做 ld:

as --32 exit.s -o exit.o
ld -m elf_i386 exit.o -o exit
#Error: -bash: ./exit: cannot execute binary file: File in wrong format
ld -m i386linux exit.o -o exit
#Error: -bash: ./exit: cannot execute binary file: File in wrong format

为了兼容性,我想补充一点,我已经安装了 Ubuntu 帮助论坛中列出的这些软件包:

sudo dpkg --add-architecture i386
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo apt-get install multiarch-support

【问题讨论】:

  • 发布您使用的确切命令以及错误。 as --32ld -melf_i386 应该可以工作。
  • 嗨@Jester 尝试并得到了上面发布的错误。
  • 看起来您的内核是在没有 CONFIG_COMPAT_BINFMT_ELF List of executable formats on Linux 的情况下构建的,因此它无法将 32 位 ELF 静态可执行文件识别为可执行文件。 (顺便说一句,x32 非常不同:它是 64 位模式下的 32 位指针en.wikipedia.org/wiki/X32_ABI。此外,x64 是仅限 Windows 的术语,Linux 使用 x86-64)。
  • 好的,谢谢指出。

标签: linux assembly x86 linker multiarch


【解决方案1】:

这些是汇编和链接 32 位静态可执行文件的正确命令。 (Assembling 32-bit binaries on a 64-bit system (GNU toolchain))

看起来您的内核是在没有 CONFIG_COMPAT_BINFMT_ELF List of executable formats on Linux 的情况下构建的,因此它无法将 32 位 ELF 静态可执行文件识别为可执行文件。 (我认为这是相关的 Linux 内核配置选项。)


或者您正在使用适用于 Linux 的 Windows 子系统,它也不支持 32 位可执行文件。

WSL 也不支持来自 64 位进程的 32 位 int 0x80 ABI,因此这也不起作用。 (What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?)。这就像一个没有 CONFIG_IA32_EMULATION 的 Linux 内核。


libc 包与此无关。您正在制作一个不依赖任何其他文件来运行的静态可执行文件

在我的 Arch Linux 系统上运行构建命令后,我得到:

$ as --32 exit.s -o exit.o
$ ld -m elf_i386 exit.o -o exit
$ file exit
exit: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
$ ./exit ; echo $?
0

所以它工作正常,你的系统只是以某种方式坏了。它要么不是真正的 Ubuntu,要么你有一个自定义内核。

【讨论】:

  • 如你所说,我使用的是 WSL。我想我需要运行一个虚拟机。谢谢你的回答。
猜你喜欢
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
  • 2013-03-06
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多