如何在 Linux 中汇编、链接和运行 .s 文件?

lun*_*kka 1 linux assembly compilation intel

当我尝试使用 AT&T Intel 语法汇编和运行 .s 文件时,收到奇怪的错误消息。不确定我是否一开始就使用了正确的架构,或者是否有语法错误,是否没有使用正确的命令来汇编和链接等。完全迷失了,我不知道从哪里开始。

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

这是我试图运行的程序,非常简单,并且没有真正执行任何操作。

resMsg: .asciz "xxxxxxxx"

.text
.global main
main:
pushq $0
ret
Run Code Online (Sandbox Code Playgroud)

我只是不明白发生了什么事。显然,这是为了学校作业。显然,我不是在寻找作业的答案,但这是我可以实际开始编码的起点。我只是不知道如何简单地运行该程序,作业中没有说明这一点。不管怎样,先谢谢大家了!

fuz*_*fuz 6

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

进一步注意,与 DOS 不同,没有任何内容可以从_start. 所以你尝试返回将会导致崩溃。相反,调用系统调用sys_exit来退出程序:

mov $0, %edi  # exit status
mov $60, %eax # system call number
syscall       # perform exit call
Run Code Online (Sandbox Code Playgroud)

或者,如果您想使用 C 运行时环境并调用 C 库中的函数,请按原样保留程序,而使用 C 编译器驱动程序进行汇编和链接cc

cc -o yea yea.s
Run Code Online (Sandbox Code Playgroud)

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

请注意,即使如此,您的代码也是不正确的。函数的返回值在寄存器中给出eaxrax而不是压入堆栈。要从 中返回零main,请写入

mov $0, %eax   # exit status
ret            # return from function
Run Code Online (Sandbox Code Playgroud)