我对 Linux (Ubuntu 10.04) 还很陌生,对汇编程序还是个新手。我正在关注一些教程,但找不到任何特定于 Linux 的内容。 所以,我的问题是,什么是编译/运行汇编程序的好包以及为该包编译/运行的命令行命令是什么?
最佳答案
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)、%rdi
和 call puts@plt
。
非 PIE 可执行文件(位置相关)可以对静态数据使用 32 位绝对寻址,但 PIE 应该使用 RIP 相对 LEA。 (另见 Difference between movq and movabsq in x86-64 movq
和 movabsq
都不是一个好的选择。)
如果您想编写 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?了解更多关于查看编译器输出以及编写有用的小函数以编译为有趣的输出的信息。
https://stackoverflow.com/questions/3314919/