assembly 我可以将自己的汇编文件/指令添加到godbolt项目中吗?

uyhoqukh  于 2023-10-19  发布在  Go
关注(0)|答案(2)|浏览(70)

正如标题所暗示的那样。比如,我想用一个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关键字,但它只是将我在那里输入的任何胡言乱语添加到汇编输出中:

tktrz96b

tktrz96b1#

使用Tree模式,您可以使用多个文件设置CMake项目,包括asm:
Godbolt Link
为了使它工作,我必须在CMakeLists.txt文件中启用nasm支持,并手动设置汇编程序的路径

set(CMAKE_ASM_NASM_COMPILER /opt/compiler-explorer/nasm-2.14.02/bin/nasm)
enable_language(ASM_NASM)
set(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp")
lmvvr0a8

lmvvr0a82#

我尝试了asm volatile关键字,但它只是将我在那里输入的任何胡言乱语添加到汇编输出中:
是的,GNU C inline asm只是将额外的文本打印到asm中。Godbolt编译器浏览器的默认操作模式是只显示编译器的asm文本输出。(Clang是不同的:与GCC不同,它有一个内置的汇编器,所以它需要你的asm语句来汇编。)
在编译器中,您可以选择“compile to binary object”来编译为.o并显示其反汇编,或者编译为链接的可执行文件(如果您的代码没有虚拟main,则包括虚拟main)并使用objdump反汇编。这将通过汇编器提供C->asm编译器(cc1cc1plus)的输出,因此如果有问题,您将得到错误。
不要在函数中使用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源代码使用了像.codefoo PROC这样的MASM指令。你需要把它改成只使用标签。因为它与调用者在同一个编译单元中,所以不需要.global test_111

// compile this with -masm=intel; the default is att
asm(R"             # multi-line string literal
.text
test_111:
    # 64-bit assembly
    # lea rax, [RIP + main]     # example of its addressing-mode syntax
    xor eax, eax
    inc rax
    ret
");

#include <iostream>

extern "C" long long test_111();
// your asm uses RAX, which would be pointless if you only return a 32-bit type

int main()
{
    long long r = test_111();

    std::cout << "result=" << r << '\n';  // endl sucks and clutters the asm
    return 0;
}

你需要把-masm=intel放在编译器命令行上;通常编译器-资源管理器只传递它的构建将停止在.s输出显示给用户,而不是一个可执行文件的单独构建运行。但是xor eax,eax在AT&T语法中是无效的;这将是两个存储器操作数和不明确的操作数大小。
在Godbolt上看到它,为编译器输出窗格检查了“执行代码”,以及一个单独的“执行器”窗格,两者都需要-masm=intel
Re:在C++中使用R"( ... )",参见 * How to write multiline inline assembly code in GCC C++? *

相关问题