【问题标题】:Compile/run assembler in Linux?在 Linux 中编译/运行汇编程序?
【发布时间】:2011-03-19 21:34:55
【问题描述】:

我对 Linux (Ubuntu 10.04) 还很陌生,对汇编程序还是个新手。我正在关注一些教程,但找不到任何特定于 Linux 的内容。 所以,我的问题是,编译/运行汇编器的好包是什么?为该包编译/运行的命令行命令是什么?

【问题讨论】:

  • 我在同一条船上。我从来没有真正在 Linux 上使用过 asm,因为没有真正的存在。也许是因为在 Windows 上破解风靡一时。
  • 这些并不能完全回答我的问题。我还是想知道你会使用哪些控制台命令来编译和运行 NASM 或 gas 中的程序
  • 我的偏好是 NASM。我在下面为您提供了一些有关如何在 Ubuntu 上启动和运行它的信息。

标签: linux ubuntu x86 assembly


【解决方案1】:

GNU 汇编器可能已经安装在您的系统上。尝试man as 以查看完整的使用信息。您可以使用as 编译单个文件并使用 ld 进行链接,如果您真的非常想要的话。

但是,GCC 是一个很棒的前端。它可以为您组装 .s 文件。例如:

$ cat >hello.s <<"EOF"
.section .rodata             # read-only static data
.globl hello
hello:
  .string "Hello, world!"    # zero-terminated C string

.text
.global main
main:
    push    %rbp
    mov     %rsp,  %rbp                 # create a stack frame

    mov     $hello, %edi                # put the address of hello into RDI
    call    puts                        #  as the first arg for puts

    mov     $0,    %eax                 # return value = 0.  Normally xor %eax,%eax
    leave                               # tear down the stack frame
    ret                            # pop the return address off the stack into RIP
EOF
$ gcc hello.s -no-pie -o hello
$ ./hello
Hello, world!

上面的代码是 x86-64。如果您想制作与位置无关的可执行文件 (PIE),则需要 lea hello(%rip), %rdicall puts@plt

非 PIE 可执行文件(位置相关)可以对静态数据使用 32 位绝对寻址,但 PIE 应该使用 RIP 相对 LEA。 (另见Difference between movq and movabsq in x86-64movqmovabsq 都不是一个好的选择。)

如果您想编写 32 位代码,调用约定是不同的,并且 RIP 相对寻址不可用。 (所以你会在调用之前push $hello,然后弹出堆栈参数。)


如果您对某些东西的工作原理感到好奇,也可以将 C/C++ 代码直接编译为汇编:

$ cat >hello.c <<EOF
#include <stdio.h>
int main(void) {
    printf("Hello, world!\n");
    return 0;
}
EOF
$ gcc -S hello.c -o hello.s

另请参阅How to remove "noise" from GCC/clang assembly output?,了解有关查看编译器输出以及编写有用的小函数以编译为有趣的输出的更多信息。

【讨论】:

    【解决方案2】:

    GNU 汇编器(gas)和 NASM 都是不错的选择。但是,它们有一些区别,最大的区别在于您放置操作的顺序及其操作数。

    gas 使用 AT&T 语法(指南:https://stackoverflow.com/tags/att/info):

    mnemonic    source, destination
    

    nasm 使用 Intel 风格(指南:https://stackoverflow.com/tags/intel-syntax/info):

    mnemonic    destination, source
    

    任何一个都可能满足您的需求。 GAS 还有一个 Intel 语法模式,它很像 MASM,而不是 NASM。


    试试这个教程:http://asm.sourceforge.net/intro/Assembly-Intro.html

    另请参阅 Stack Overflow 的 x86 tag wiki 中指向指南和文档的更多链接

    【讨论】:

    • 谢谢,该教程很棒,因为它是针对 Linux 的。此外,本教程对如何在 linux 中编译和运行汇编程序有非常具体的说明
    • gas 支持“.intel_syntax”有一段时间了——不过我个人还是会使用 fasm、yasm 或 nasm。
    【解决方案3】:

    如果您使用的是 NASM,则命令行只需

    nasm -felf32 -g -Fdwarf file.asm -o file.o
    

    其中“file.asm”是您的程序集文件(代码),“file.o”是您可以与gcc -m32ld -melf_i386 链接的目标文件。 (使用nasm -felf64 组装将生成一个 64 位目标文件,但下面的 hello world 示例使用 32 位系统调用,并且在 PIE 可执行文件中不起作用。)

    这里有更多信息:

    http://www.nasm.us/doc/nasmdoc2.html#section-2.1

    您可以使用以下命令在 Ubuntu 中安装 NASM:

    apt-get install nasm
    

    这里有一个基本的 Linux 程序集 Hello World 来激发你的胃口:

    http://web.archive.org/web/20120822144129/http://www.cin.ufpe.br/~if817/arquivos/asmtut/index.html

    我希望这就是你要问的......

    【讨论】:

    • Hello World 示例链接失效!
    【解决方案4】:

    还有适用于 Linux 的 FASM。

    format ELF executable
    
    segment readable executable
    
    start:
    mov eax, 4
    mov ebx, 1
    mov ecx, hello_msg
    mov edx, hello_size
    int 80h
    
    mov eax, 1
    mov ebx, 0
    int 80h
    
    segment readable writeable
    
    hello_msg db "Hello World!",10,0
    hello_size = $-hello_msg
    

    它伴随着

    fasm hello.asm hello
    

    【讨论】:

      【解决方案5】:

      我的建议是从头开始编程这本书:

      http://nongnu.askapache.com/pgubook/ProgrammingGroundUp-1-0-booksize.pdf

      这是进入 linux 下的汇编程序编程的一个很好的起点,它解释了很多入门需要了解的基础知识。

      【讨论】:

        【解决方案6】:

        汇编器(GNU)是 as(1)

        【讨论】:

          【解决方案7】:

          1 个汇编程序 yasm 中的 3 种语法(nasm、tasm、gas)。

          http://www.tortall.net/projects/yasm/

          【讨论】:

            【解决方案8】:

            对于 Ubuntu 18.04 安装nasm 。打开终端并输入:

            sudo apt install as31 nasm

            nasm 文档

            用于编译和运行:

            nasm -f elf64 example.asm # assemble the program  
            ld -s -o example example.o # link the object file nasm produced into an executable file  
            ./example # example is an executable file
            

            【讨论】:

            • as31 是 8051 代码的汇编器。 Linux 不能在 8051 微控制器上运行,因此你不能在你的 Linux 机器上链接然后运行任何你用它组装的东西(这就是这个问题的意义所在)。
            • @Geancarlo Murillo 这只是最好的答案。太感谢了。这非常有效。正是我需要的!
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-01-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多