LLVM具有使我们能够将本机汇编指令直接放入.ll
文件中的功能。
module asm "inline asm code goes here"
https://llvm.org/docs/LangRef.html#module-level-inline-assembly
实际上,.s
输出文件包含这些指令。
但是我该如何编写一个完整的函数并从同一个文件中的LLVM代码调用它呢?
有人可以提供一个简单的示例.ll
,其中以LLVM代码编写的@main()
调用到内联module asm
中定义的函数中(理想情况下传递一个或两个参数)并退出的返回值?
我问是因为我想将this code从NASM移植到LLIR。它直接使用系统调用输出Hello World,而无需链接到标准库(因此,如果有一种方法可以进行系统调用而又无需进入本机程序集,那么我也想听听)。
答案 0 :(得分:2)
我不确定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