正如标题所暗示的那样。比如,我想用一个Godbolt项目来做这件事:main.cpp
#include <iostream>
extern "C" int test_111();
int main()
{
int r = test_111();
std::cout << "result=" << r << std::endl;
return 0;
}
然后在asm1.asm
中:
.code
test_111 PROC
; 64-bit assembly
xor eax, eax
inc rax
ret
test_111 ENDP
END
在“x86-64 clang”下尝试(任何版本)。
但我不知道该怎么做。有什么建议吗?
PS.目标是将我自己的汇编指令注入到输出中。
编辑:
在注解中给出建议后,我尝试了asm volatile
关键字,但它只是将我在那里输入的任何胡言乱语添加到汇编输出中:
2条答案
按热度按时间tktrz96b1#
使用Tree模式,您可以使用多个文件设置CMake项目,包括asm:
Godbolt Link
为了使它工作,我必须在
CMakeLists.txt
文件中启用nasm
支持,并手动设置汇编程序的路径lmvvr0a82#
我尝试了asm volatile关键字,但它只是将我在那里输入的任何胡言乱语添加到汇编输出中:
是的,GNU C inline asm只是将额外的文本打印到asm中。Godbolt编译器浏览器的默认操作模式是只显示编译器的asm文本输出。(Clang是不同的:与GCC不同,它有一个内置的汇编器,所以它需要你的asm语句来汇编。)
在编译器中,您可以选择“compile to binary object”来编译为
.o
并显示其反汇编,或者编译为链接的可执行文件(如果您的代码没有虚拟main
,则包括虚拟main
)并使用objdump
反汇编。这将通过汇编器提供C->asm编译器(cc1
或cc1plus
)的输出,因此如果有问题,您将得到错误。不要在函数中使用Basic Asm(没有约束),除非是
__attribute__((naked))
,在这种情况下,Basic Asm是你唯一可以放在那里的东西。https://gcc.gnu.org/wiki/ConvertBasicAsmToExtended**不过,您可以在 global 范围内使用Basic Asm,几乎完全像一个单独的
.s
文件一样,使用GNU assembler's.intel_syntax noprefix
,这与MASM类似,而不是指令。您可以从Godbolt上的looking at GCC and Clang output for simple C/C++ functions获得有效语法的示例。(您问题中的asm源代码使用了像
.code
和foo PROC
这样的MASM指令。你需要把它改成只使用标签。因为它与调用者在同一个编译单元中,所以不需要.global test_111
)你需要把
-masm=intel
放在编译器命令行上;通常编译器-资源管理器只传递它的构建将停止在.s
输出显示给用户,而不是一个可执行文件的单独构建运行。但是xor eax,eax
在AT&T语法中是无效的;这将是两个存储器操作数和不明确的操作数大小。在Godbolt上看到它,为编译器输出窗格检查了“执行代码”,以及一个单独的“执行器”窗格,两者都需要
-masm=intel
。Re:在C++中使用
R"( ... )"
,参见 * How to write multiline inline assembly code in GCC C++? *