首页 > 解决方案 > 使用 as 和 ld 在 x86-64 Linux 上组装并运行 i386 asm 程序

问题描述

所以我是新尝试 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

现在..我一直在寻找如何做到这一点,并发现了--32in as 和-m {arg}inld但是每次我编译它而没有拱形错误时,它都会给我“文件格式错误”错误。

我试过用 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

标签: linuxassemblyx86linkermultiarch

解决方案


这些是汇编和链接 32 位静态可执行文件的正确命令。(在 64 位系统上组装 32 位二进制文​​件(GNU 工具链)

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


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

WSL 也不支持int 0x80来自 64 位进程的 32 位 ABI,因此这也不起作用。(如果在 64 位代码中使用 32 位 int 0x80 Linux ABI 会发生什么?)。这就像一个没有 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,要么你有一个自定义内核。


推荐阅读