什么是字符串?字符数组。
什么是角色?一个整数。
因此,虽然我无论如何都不是 LLVM 专家,但我猜想,例如,如果您想表示某个 8 位字符集,您会使用 i8 数组(8 位整数),或者指向i8。事实上,如果我们有一个简单的 hello world C 程序:
#include <stdio.h>
int main() {
puts("Hello, world!");
return 0;
}
我们使用 llvm-gcc 编译它并转储生成的 LLVM 程序集:
$ llvm-gcc -S -emit-llvm hello.c
$ cat hello.s
; ModuleID = 'hello.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-linux-gnu"
@.str = internal constant [14 x i8] c"Hello, world!\00" ; <[14 x i8]*> [#uses=1]
define i32 @main() {
entry:
%retval = alloca i32 ; <i32*> [#uses=2]
%tmp = alloca i32 ; <i32*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
%tmp1 = getelementptr [14 x i8]* @.str, i32 0, i64 0 ; <i8*> [#uses=1]
%tmp2 = call i32 @puts( i8* %tmp1 ) nounwind ; <i32> [#uses=0]
store i32 0, i32* %tmp, align 4
%tmp3 = load i32* %tmp, align 4 ; <i32> [#uses=1]
store i32 %tmp3, i32* %retval, align 4
br label %return
return: ; preds = %entry
%retval4 = load i32* %retval ; <i32> [#uses=1]
ret i32 %retval4
}
declare i32 @puts(i8*)
请注意对文件末尾声明的 put 函数的引用。在 C 语言中,puts 是
int puts(const char *s)
在LLVM中,它是
i32 @puts(i8*)
对应关系应该清晰。
顺便说一句,生成的 LLVM 非常冗长,因为我编译时没有进行优化。如果您打开它们,不必要的说明就会消失:
$ llvm-gcc -O2 -S -emit-llvm hello.c
$ cat hello.s
; ModuleID = 'hello.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-linux-gnu"
@.str = internal constant [14 x i8] c"Hello, world!\00" ; <[14 x i8]*> [#uses=1]
define i32 @main() nounwind {
entry:
%tmp2 = tail call i32 @puts( i8* getelementptr ([14 x i8]* @.str, i32 0, i64 0) ) nounwind ; <i32> [#uses=0]
ret i32 0
}
declare i32 @puts(i8*)