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

我对 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)、%rdicall puts@plt

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

如果您想编写 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/

相关文章:

linux - 设置 Apache 用户的 umask

python - 如何在 python 中获得单调持续时间?

linux - 如何获取使用 nohup 运行的程序列表

python - 我可以使用 `pip` 而不是 `easy_install` 进行 `python

python - 你如何为 python 模块的 argparse 部分编写测试?

python - 通过索引访问 collections.OrderedDict 中的项目

linux - 只删除linux目录中的文件而不是目录

linux - 解释段错误消息

python - 如何获取python列表的第n个元素或默认值(如果不可用)

python - virtualenv --no-site-packages 和 pip 仍在寻找全