【发布时间】:2020-03-29 06:34:00
【问题描述】:
不幸的是,互联网上缺乏关于如何在 C 程序中实现 x86 汇编的指南。此外,新手想知道不同的语法(IT&T 和英特尔)。
就我个人而言,我不确定如何处理不同的编译器/汇编器,如 NASM 或 GCC。
我创建了以下高度复杂的程序:
#include <stdio.h>
extern int add_imm(int,int);
int main(int argv, char** argc){
int a = 2;
int b = 3;
int c = add_imm(a,b);
printf("%d", c);
}
与其他高度复杂的程序一起使用:
SECTION .TEXT
GLOBAL add_imm
add_imm:
push rbp
mov rsp, rbp
mov rax, [rbp+24]
mov rbx, [rbp+16]
add rax, rbx
pop rbp
ret
编译:
nasm -f elf64 add_imm.S
gcc main.c add_imm.o -o tes
引发编译器错误:
Undefined symbols for architecture x86_64:
"_add_imm", referenced from:
_main in main-019ea6.o
ld: symbol(s) not found for architecture x86_64
所以我认为如果有人能够解释如何将汇编语言真正嵌入到 C 中,那将是值得的。 什么是重要的考虑?什么是通用调用约定?
注意:我使用的是 macOS,但我希望它也能在 Linux 上运行。
【问题讨论】:
-
你在为什么操作系统编程?
-
请注意,调用约定也很可能是错误的。但如果不知道您正在为什么操作系统编程,我无法确定。
-
@fuz:我认为 GCC 没有被移植到任何标准调用约定是堆栈参数的 x86-64 操作系统。 AFAIK 唯一支持的 3 个约定是 x86-64 SysV 和 Windows x64 fastcall 和 vectorcall(相同,但
__m128在 XMM regs 中传递而不是通过引用传递)。 -
@PeterCordes 确实如此。这不正是我在原始评论中写的吗?顺便说一句,Go 在 amd64 上使用仅堆栈调用约定,所以就是这样。
-
MacOS 是 Unix。您可能会争辩说,它比 Linux 更重要,因为它的传统可以追溯到 FreeBSD。 Linux 是 Unix 的重新实现,并且符合 POSIX,但有些人不喜欢称它为 Unix。或者您的意思是像 x86-64 Solaris 或原始 FreeBSD、OpenBSD 或 NetBSD 这样的 Unix?