linux - 使用 as 和 ld 在 x86-64 Linux 上组装并运行 i386 asm 程序
问题描述
所以我是新尝试 asm,我想编译一个小程序,它只使用 i386 指令而不是 x86-64 指令退出。我有一个 x86-64 Ubuntu,它可以完美地编译和运行 x86-64,但我不知道如何在同一台 x86-64 机器上组装和链接 i386 版本(我已经安装了 i386 compat)。
我知道已经回答了类似的问题,但是他们都没有使用as
并ld
做到这一点,所以我不知道如何将这些解决方案转化为我的问题。
对于我使用的 x86-64 as
,ld
如下所示:
# 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
现在..我一直在寻找如何做到这一点,并发现了--32
in 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
解决方案
这些是汇编和链接 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,要么你有一个自定义内核。