如何使用LLVM模块级内联程序集定义和调用函数?
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,
.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依赖项。