我正在尝试使用 NASM 和 gcc 来学习 Linux 上的 x86-64 汇编。我已经制作了最简单的可以想象的汇编函数,它除了返回 0 之外什么也不做。这是
corr.asm
:
global corr
default rel
section .text:
corr:
mov rax, 0
ret
然后我有一个 C 文件,其中包含调用该函数并打印其返回值的代码。这是
test.c
:
#include <stdio.h>
#include <stdint.h>
extern int64_t corr(void);
int main(void) {
int64_t x = corr();
printf("Result: %u\n", x);
return 0;
}
最后,我将其编译为可执行文件并像这样运行它:
nasm -f elf64 -o corr.o corr.asm
gcc -c -o test.o test.c
gcc corr.o test.o -o test
./test
不幸的是,即使是这么低的障碍显然也会带来绊倒危险,其形式是立即出现段错误并且没有输出。我尝试过删除
default rel
,删除 extern
,然后删除两者。我已经在 gdb 中尝试过单步指令,但它告诉我的是,当它尝试输入我的函数时,它会在 call
指令上出现段错误,这对我来说就像这一样令人困惑。即使没有 mov rax, 0
,段错误仍然存在。
我四处寻找人们从 C 调用 NASM x86-64 函数的示例,并找到了一些。例如,https://www.cs.umd.edu/class/spring2021/cmsc430/a86.html显示了构建可执行文件的基本相同的命令,它们的汇编函数的不同之处仅在于它实际上做了一些有价值的事情。我不明白为什么他们的应该工作而我的不应该。
ecm 的评论是绝对正确的 - 如果我写
section .text
没有冒号,它可以正常工作并打印 Result: 0
。在程序运行之前,这是一个完全无声的“错误”。