【发布时间】:2016-06-01 19:52:42
【问题描述】:
我是汇编语言编程的新手。我正在尝试按照here 概述的步骤来更好地了解组装和优化。我的操作系统是 Linux Mint,我正在尝试使用 NASM 汇编程序,尽管没有成功。
和演练一样,代码是:
BITS 32
GLOBAL main
SECTION .text
main:
mov eax, 42
ret
使用 nasm 编译成功,使用命令:nasm -f elf tiny.asm
但如果我尝试使用 gcc 与命令链接:gcc -Wall -s tiny.o
我收到以下错误: /usr/bin/ld: 输入文件 `tiny.o' 的 i386 架构与 i386:x86-64 输出不兼容
快速搜索告诉我应该使用以下 ld 命令链接:ld -m elf_i386 -s -o tiny tiny.o
但是,这样做会给我以下警告: ld:警告:找不到入口符号_start;默认为 0000000008048060
如果我 ./tiny 我得到一个分段错误。并且./tiny ; echo $? 还返回数字“139”,这是......意想不到的。
环顾四周,我发现通过将 1 传递给 eax 寄存器并将 0 传递给 ebx 并使用我不熟悉的 int 命令来结束程序,解决了一些问题......但考虑到我的目标是让程序尽可能小,我宁愿不添加额外的代码行。
我应该添加编译和链接这个类似的代码(GAS):
.global main
.text
main:
mov $32, %eax
使用 gcc 编译器似乎可以完美运行。我在这里不知所措。任何正确方向的观点都将不胜感激。
【问题讨论】:
-
如果您在 64 位 Linux Mint 上并尝试创建 32 位应用程序(使用 GCC 链接)尝试执行
sudo apt-get install gcc-multilib g++-multilib然后尝试nasm -f elf32 tiny.asm和gcc -m32 -Wall -s tiny.o -o tiny -
非常感谢!这为我解决了所有问题,您介意再解释一下附加选项的作用吗?他们只是让 32 位代码在 64 位环境中运行吗?
-
默认情况下,GCC 创建 32 位程序所需的文件未安装在 64 位 Linux 上。
sudo apt get...行简单地下载并安装在 64 位 Linux Mint 上进行 32 位 GCC 开发所需的 GCC 文件。由于您在汇编程序的顶部有BITS 32,因此您希望将其编译为nasm -f elf32 tiny.asm所做的32 位ELF 对象)(它默认输出一个名为tiny.o的文件。对象文件需要链接到一个可执行文件gcc -m32 -Wall -s tiny.o -o tiny就是这样做的。我添加的-m32选项表示我们要从32 位对象生成一个32 位可执行文件。 -
通过使用 GCC 链接可执行文件,生成的程序实际上做了一些 C 运行时初始化,然后像 C 一样调用名为
main的标签 函数。当您在main中执行ret时,它会返回到 C 运行时代码并为您干净地退出程序。
标签: gcc assembly x86 linker-errors ld