【发布时间】: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