【问题标题】:Compiling 32-bit assembly on 64-bit Ubuntu on Windows [duplicate]在 Windows 上的 64 位 Ubuntu 上编译 32 位程序集 [重复]
【发布时间】:2018-05-02 21:09:15
【问题描述】:

编辑:看起来问题在于 Linux 的 Windows 子系统无法处理 32 位。

Assembly 和 linux 新手在这里尝试在 Windows 上的 64 位 Ubuntu 上编译 32 位程序集(AT&T 语法)。我的情况实际上是this other stackoverflow question 的精确复制品,但由于某种原因,那里的解决方案(我在许多其他帖子中看到重复)对我不起作用。我正在使用 Programming from the Ground Up 一书学习 x86 汇编,但我无法在 Windows 上的 Ubuntu 上的 Bash 上编译程序。

我在我的命令中尝试了多种选项组合,有些显然可以编译,但我要么无法执行二进制文件(格式错误),要么可以但当我到达 @987654329 时出现分段错误@ 在我的源文件中(我读到这可能是由于在 64 位环境中设置了 32 位堆栈)。

没有.32code 作为我的程序的第一行,并且没有--32 选项as,没有尝试使用ld 产生任何有用的东西:without .32code and with --32(还不能在我的帖子中嵌入图像所以而是放置链接)。

仍然没有.32code,现在有了--x32 (without .32code and with --x32),我发现如果你不包括.32code,它在推送、弹出等方面有问题,所以在这里我将它包括在我的源代码中文件:with .32code and with --x32.

然后,我可以用gcc 代替as 和ld 进行类似的尝试,但我不确定包含所有不同的故障组合并打开蠕虫罐是否有意义因为然后我们进入 gcc 是否有它需要的库(?)。例如,使用gcc -m32 -nostdlib factorial.s -o factorial,我收到“无法执行二进制文件:执行格式错误”消息,无论是否使用.32code。尝试诸如sudo apt-get install lib32gcc-4.8-dev 和其他尝试之类的东西,似乎没有任何效果,而且很多时候我遇到qemu-user-static 的问题,可能是因为我曾经安装过它,但现在全是 f%^#!d。

一个答案建议只安装 32 位 gcc,但这似乎对我没有任何帮助。另一种解决方案可能是将书中的所有示例手动转换为 64 位,然后忘记所有这些。我想这意味着将堆栈重新设想为包含 8 个而不是 4 个(即,4(%esp) 之类的东西将变为8(%esp))但也可能将一些movl 更改为movq,例如,或一些@ 987654348@ 到%rax 等。但我觉得应该有一些解决方案,尤其是how the poster in 2013 似乎已经解决了确切的问题。也许我需要用-march=CPU[+EXTENSION...] 或-mtune=CPU 之类的东西再试一次?也许我只是缺乏架构、linux、as/gcc 的基础知识?

【问题讨论】:

  • ld -melf_i386 是要使用的正确仿真。
  • @Jester 感谢您的提示,但考虑到该仿真,我已尝试在我的 .s 文件中使用 .32code,但 as --32 和 as --x32 似乎都不起作用。然后,取出.32code 并重试两个as 选项也不起作用:see here
  • 您得到了正确的 32 位二进制输出。现在要弄清楚为什么你的 ubuntu 不会运行它。你在使用 WSL 吗?显然这只是doesn't support 32 bit。
  • @Jester,废话,这可能一直是问题吗?该链接似乎暗示 Windows 的 Linux 子系统似乎无法处理 32 位。我想我现在可能需要在虚拟机上安装 Ubuntu...
  • 要从 asm 源代码构建 32 位二进制文​​件(带/不带 libc 或 CRT 启动文件),请参阅stackoverflow.com/questions/36861903/…。如果您只定义_start:,gcc -m32 -static -nostdlib foo.S 应该可以工作。

标签: linux ubuntu gcc assembly x86


【解决方案1】:

我认为你的汇编器工作正常。如果要链接已安装的 glibc 版本,则需要确保安装 i386 版本的开发包(可能是 libc6-dev:i386,但也可能是 libc6-dev-i386,具体取决于发行版本),并用 @ 链接987654325@ 获得正确的路径。然后gcc 编译器驱动程序将使用适当的标志为您调用ld。

您可以通过编译和链接一个带有gcc -m32 的小C 文件来验证您的设置是否有效。这应该会生成一个 32 位程序。

【讨论】:

  • 感谢您的提示,这可能会让我在诊断问题方面有所帮助。您会在the image 中看到libc6-dev:i386、libc6-dev-i386 和gcc-multilib 的最新版本已经安装,并且我认为我的gcc 版本是x86_64。所以使用this C example,它会警告我关于 32 位编译(错误的 C 程序或错误的 32-but gcc?)但它与 64-but 编译没有问题。是因为我的 gcc 是 x86_64 吗?
  • @JaimeSalazar:您是否在适用于 Linux 的 Windows 子系统(适用于 Windows 10 的 Ubuntu)中运行此代码?
  • @JaimeSalazar WSL 似乎无法执行 32 位二进制文​​件。
  • @fuz 是的,感谢 Jester,我在几分钟前发现了 -.- 谢谢大家,会更新我的问题
  • @JaimeSalazar 请将此知识发布为答案,以便偶然发现您的问题的人快速找到它。
猜你喜欢
  • 2023-03-20
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
相关资源
最近更新 更多