如何使用LLVM模块级内联程序集定义和调用函数?

如何使用LLVM模块级内联程序集定义和调用函数?,llvm,llvm-ir,Llvm,Llvm Ir,LLVM有一个特性,允许我们将本机汇编指令直接放入.ll文件中 module asm "inline asm code goes here" 实际上,.s输出文件包含这些指令 但是,我如何以这种方式编写完整的函数,并从同一文件中的LLVM代码调用它呢 有人能提供一个简单的例子.ll,其中在LLVM代码中编写的@main()调用内联模块asm中定义的函数(理想情况下传递一个或两个参数)并以返回值退出吗 我这样问是因为我想从NASM移植到LLIR。它直接使用系统调用输出Hello World,

LLVM有一个特性,允许我们将本机汇编指令直接放入
.ll
文件中

 module asm "inline asm code goes here"

实际上,
.s
输出文件包含这些指令

但是,我如何以这种方式编写完整的函数,并从同一文件中的LLVM代码调用它呢

有人能提供一个简单的例子
.ll
,其中在LLVM代码中编写的
@main()
调用内联
模块asm
中定义的函数(理想情况下传递一个或两个参数)并以返回值退出吗


我这样问是因为我想从NASM移植到LLIR。它直接使用系统调用输出Hello World,而无需与标准库链接(因此,如果有一种方法可以进行系统调用而无需进入本机程序集,我也想听听这个)。

我不确定llvm模块级内联程序集是否可以与nasm风格一起工作。 希望下面列出的例子能给你一些启示。基本上,我们希望在llvm ir中声明函数,该函数将在链接时解析

; source_filename = file.ll

module asm ".format:"
module asm "    .string \22%d, hello world %s\n\22"
module asm "    .text"
module asm "    .globl print"
module asm "    .type print @function"
module asm "print:"
module asm "        pushq   %rbp"
module asm "        movq    %rsp, %rbp"
module asm "        subq    $16, %rsp"
module asm "        movl    %edi, -4(%rbp)"
module asm "        movq    %rsi, -16(%rbp)"
module asm "        movq    -16(%rbp), %rdx"
module asm "        movl    -4(%rbp), %eax"
module asm "        movl    %eax, %esi"
module asm "        leaq    .format(%rip), %rdi"
module asm "        movl    $0, %eax"
module asm "        call    printf@PLT"
module asm "        movq    %rbp, %rsp"
module asm "        popq    %rbp"
module asm "        ret"

@.str = global [16 x i8] c", how are you?\0A\00"

declare void @print(i64, i8*)

define i32 @main() {
start:
  %cast210 = getelementptr [16 x i8], [16 x i8]* @.str, i64 0, i64 0
  call void @print(i64 10, i8* %cast210)
  ret i32 0
}
编译并运行

llc file.ll -filetype=obj -o file.o
ld -o test ./file.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o -lc -melf_x86_64
./test

谢谢,我稍后再试。它不必是NASM语法。为什么要在结尾调用gcc?llvm不包括这样做的工具吗?是的,这里不需要gcc,任何健全的链接器(llvm有lld,您可以使用lld、ld或gold ld)都可以完成这项工作,因为汇编子例程使用“printf”std-lib链接是必需的,坦率地说,我懒得解决外部c-runtime依赖项。