【问题标题】:How do you assemble, link and run a .s file in linux?如何在 linux 中组装、链接和运行 .s 文件?
【发布时间】:2019-07-31 12:51:05
【问题描述】:

尝试使用 AT&T 英特尔语法组装和运行 .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

我只是不知道发生了什么。显然,这是为了学校作业。显然,我不是在寻找作业的答案,但这是我可以实际开始编码的起点。而且我只是不知道如何简单地运行程序,它在作业中没有说。无论如何,提前谢谢你们!

【问题讨论】:

    标签: linux assembly compilation intel


    【解决方案1】:

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

    进一步注意,与 DOS 不同,_start 没有可返回的内容。因此,您返回的尝试将导致崩溃。而是调用系统调用sys_exit退出程序:

    mov $0, %edi  # exit status
    mov $60, %eax # system call number
    syscall       # perform exit call
    

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

    cc -o yea yea.s
    

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

    请注意,即使那样您的代码也不正确。函数的返回值在eax (resp. rax) 寄存器中给出,而不是压入堆栈。要从 main 返回零,请编写

    mov $0, %eax   # exit status
    ret            # return from function
    

    【讨论】:

    • 哇,非常感谢!是的,实际上作业是关于编写可在 C 程序中使用的汇编程序。要试试这个,非常感谢!
    • @lunarkakka 谢谢。另请注意,没有“AT&T Intel 语法”。有 AT&T 语法(这是 UNIX as 使用的)和 Intel 语法(这是许多其他汇编程序使用的)。确保您始终使用准确和正确的术语来表达您正在谈论的事情,否则其他人会非常困惑。
    • @lunarkakka 当您的问题得到解决后,不要忘记将答案标记为已接受。这向其他用户表明他们可以将精力集中在其他问题上。
    • cannot find entry symbol _start; defaulting to 000000440000 不是错误,只是ld 警告。如果没有导出/全局 _start 符号,ld 默认使用 .text 部分的开头作为入口点。这适用于一次性/玩具实验,例如在文件中粘贴几条指令,以便您可以使用 GDB 单步执行它们。 OP 的代码可能会组装 + 链接,如果运行,则在 ret 到绝对地址 0 之后的代码提取上会出现段错误。你的答案是正确的:他们实际上应该做什么:使用 C 编译器构建,将调用 main.
    【解决方案2】:

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

    sudo apt install as31 nasm
    as31:英特尔 8031/8051 汇编器 这是一个快速、简单、易于使用的 Intel 8031/8051 汇编器。

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

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

    nasm -f elf64 example.asm # 汇编程序
    ld -s -o example example.o # 将 nasm 生成的目标文件链接成可执行文件
    ./example #example 是一个可执行文件

    【讨论】:

    • 为什么让他们安装as31
    • 这不是 OP 想要的汇编器。
    猜你喜欢
    • 1970-01-01
    • 2016-03-31
    • 2014-10-25
    • 1970-01-01
    • 2021-05-15
    • 2017-08-28
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多