assemble、link 和 运行 如何在 linux 中生成 .s 文件?

How do you assemble, link and run a .s file in linux?

我在尝试使用 AT&T 英特尔语法 assemble 和 运行 .s 文件时收到奇怪的错误消息。不确定我是否一开始就使用了正确的架构,或者我是否有语法错误,如果我没有使用正确的命令 assemble 和 link,等等。完全丢失我不知道从哪里开始。

所以基本上,我有一个名为 yea.s 的文件,其中包含一些简单的 assembler 说明。然后我尝试使用命令 as yea.s -o yea.o 编译它,然后 link 使用 ld yea.o -o yea。当 运行ning ld 时,我收到这条奇怪的消息:ld: warning: cannot find entry symbol _start; defaulting to 000000440000

这是我正在尝试 运行 的程序,非常简单,实际上什么都不做。

resMsg: .asciz "xxxxxxxx"

.text
.global main
main:
pushq [=14=]
ret

我只是不知道发生了什么。显然,这是学校作业。显然,我不是在寻找家庭作业的答案,但这是我可以真正开始编码的起点。而且我只是不知道如何简化 运行 程序,它在作业中没有说明。无论如何,提前谢谢大家!

在所有当前支持的 Ubuntu 版本中打开终端并输入:

sudo apt install as31 nasm
as31:英特尔 8031/8051 assembler 这是一款快速、简单、易于使用的 Intel 8031/8051 assembler.

nasm:通用 x86 assembler 全网汇编程序。 NASM 当前将输出平面形式的二进制文件、a.out、COFF 和 ELF Unix 目标文件,以及 Microsoft 16 位 DOS 和 Win32 目标文件。

如果您在 Ubuntu 18.04 中使用 NASM,编译命令和 运行 名为 example.asm 的 .asm 文件是:

nasm -f elf64 example.asm # assemble 程序
ld -s -o example example.o # link 目标文件 nasm 产生为可执行文件
./example # example 是一个可执行文件

Linux 可执行文件需要指定入口点。入口点是程序中要执行的第一条指令的地址。如果没有另外指定,link 编辑器会查找名为 _start 的符号作为入口点。您的程序不包含这样的符号,因此 linker 抱怨并选择 .text 部分的开头作为入口点。要解决此问题,请将 main 重命名为 _start.

进一步注意,与 DOS 不同,return 与 _start 没有任何关系。因此,您对 return 的尝试将导致崩溃。相反,调用系统调用 sys_exit 退出程序:

mov [=10=], %edi  # exit status
mov , %eax # system call number
syscall       # perform exit call

或者,如果您想使用 C 运行时环境并调用 C 库中的函数,请保持程序不变,而不是 assemble 和 link 使用 C 编译器驱动程序 cc:

cc -o yea yea.s

如果您这样做,C 运行时环境会为您提供入口点,并最终尝试调用一个函数 main,这就是您的代码所在的位置。如果您想调用函数,则需要这种方法来自 C 库。如果您这样做,请确保 main 遵循 SysV ABI(调用约定)。

请注意,即使这样您的代码也不正确。函数的 return 值在 eax(相应的 rax)寄存器中给出,而不是压入堆栈。从 main 到 return 零,写入

mov [=12=], %eax   # exit status
ret            # return from function