在Linux中编译/运行汇编程序?

时间:2010-07-23 02:11:45

标签: linux ubuntu x86 assembly

我是Linux的新手(Ubuntu 10.04),也是汇编程序的新手。我正在学习一些教程,但我找不到任何特定于Linux的内容。 所以,我的问题是,什么是编译/运行汇编程序的好包以及为该程序包编译/运行的命令行命令是什么?

8 个答案:

答案 0 :(得分:57)

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可执行文件(position- dependent )可以对静态数据使用32位绝对寻址,但PIE应使用RIP相对LEA。 (另请参阅Difference between movq and movabsq in x86-64 movqmovabsq都不是一个好选择。)

如果要编写32位代码,则调用约定不同,并且RIP相对寻址不可用。 (所以你在调用之前push $hello,并在之后弹出堆栈args。)


如果你好奇某些东西是如何工作的,你也可以直接将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?以获取有关查看编译器输出以及编写将编译为有趣输出的有用小函数的更多信息。

答案 1 :(得分:43)

GNU汇编程序(气体)和NASM都是不错的选择。但是,它们有一些差异,最重要的是你操作的顺序和操作数。

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

mnemonic    source, destination

nasm使用英特尔风格(指南: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

中指南和文档的更多链接

答案 2 :(得分:20)

如果您使用的是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

我希望这就是你所要求的......

答案 3 :(得分:8)

还有适用于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

答案 4 :(得分:7)

我的建议是从“从头开始编程:

”这本书

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

这是进入Linux下汇编程序编程的一个非常好的起点,它解释了开始时需要了解的许多基础知识。

答案 5 :(得分:4)

汇编程序(GNU)为(1)

答案 6 :(得分:4)

3汇编语言中的语法(nasm,tasm,gas),yasm。

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

答案 7 :(得分:1)

对于 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