问题描述
我是Linux的新手(Ubuntu 10.04),也是汇编程序的新手。我正在学习一些教程,但我找不到任何特定于Linux的内容。所以,我的问题是,什么是编译/运行汇编程序的好包,以及为该程序包编译/运行的命令行命令是什么?
最佳解决方案
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-syntax模式,它很像MASM,而不是NASM。
试试本教程:http://asm.sourceforge.net/intro/Assembly-Intro.html
另请参阅Stack Overflow的x86 tag wiki中指南和文档的更多链接
次佳解决方案
GNU汇编程序可能已经安装在您的系统上。尝试使用man as
查看完整的使用信息。您可以使用as
编译单个文件,如果您真的想要,可以使用ld链接。
然而,GCC制造了一个伟大的front-end。它可以为您组装.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。如果要制作position-independent可执行文件(PIE),则需要lea hello(%rip), %rdi
和call puts@plt
。
non-PIE可执行文件(position-dependent)可以对静态数据使用32位绝对寻址,但PIE应使用RIP-relative LEA。 (另请参阅Difference between movq and movabsq in x86-64,movq
和movabsq
都不是一个好选择。)
如果要编写32位代码,则调用约定不同,并且RIP-relative寻址不可用。 (所以你在调用之前会遇到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?以获取有关查看编译器输出以及编写将编译为有趣输出的有用小函数的更多信息。
第三种解决方案
如果您使用的是NASM,那么命令行就是
nasm -felf32 -g -Fdwarf file.asm -o file.o
其中’file.asm’是您的汇编文件(代码),’file.o’是可以与gcc -m32
或ld -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
我希望这就是你要问的……
第四种方案
还有适用于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
第五种方案
我的建议是从头开始编程:
http://nongnu.askapache.com/pgubook/ProgrammingGroundUp-1-0-booksize.pdf
这是在linux下进入汇编程序编程的一个非常好的起点,它解释了入门时需要了解的许多基础知识。
第六种方案
汇编程序(GNU)如(1)
第七种方案
1个汇编语言中的3个语法(nasm,tasm,gas),yasm。
http://www.tortall.net/projects/yasm/