代码之家  ›  专栏  ›  技术社区  ›  Thilo

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

  •  1
  • Thilo  · 技术社区  · 8 年前

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

     module asm "inline asm code goes here"
    

    https://llvm.org/docs/LangRef.html#module-level-inline-assembly

    事实上 .s 输出文件包含这些指令。

    但是,我怎样才能以这种方式编写一个完整的函数并从同一个文件中的LLVM代码调用它呢?

    有人能举个简单的例子吗 小二 在哪里 @main() module asm (理想情况下传递一个或两个参数)并以返回值退出?

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

    1 回复  |  直到 8 年前
        1
  •  2
  •   Chirag Patel    8 年前

    我不确定llvm模块级内联汇编是否能与nasm风格兼容。

    ; 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