LLVM生成中间码以及汇编代码

首先先贴一个LLVM安装的教程:

原文地址:

  http://thread.gmane.org/gmane.comp.compilers.llvm.klee/923

打不开就用:

  http://blog.csdn.net/happygogf/article/details/17528059

这个文章整合了klee和llvm的安装,由于这两个软件都要用到,所以这样装上之后问题比较少。如果直接安装llvm,会造成一大堆乱七八糟的错误,特别是找不到一些lib,也有可能是我安装的方法不对?

 

使用的帖子:

http://blog.tinlans.org/2010/09/10/%E6%8B%96%E7%A8%BF%E5%BE%88%E4%B9%85%E7%9A%84-llvm-%E4%BD%BF%E7%94%A8%E6%96%87/

虽然是个台湾的帖子,但是是我看到的llvm使用分析的最全面的了。也有可能因为墙的原因,没有看到国外的一些帖子。其中稍微有点区别,文章里使用的clang,但是我一般使用llvm-gcc,在高版本的llvm里已经没有llvm-gcc了,因为要使用klee,klee限制了llvm的版本,所以还能使用llvm-gcc。

 

下面的命令用了有一段时日了,下次试一下确认一下如果有错再来编辑原文吧(果然有更新,修改一次)。

利用llvm-gcc很容易得到中间码IR:

llvm-gcc -emit-llvm -c hello.c -o hello.bc   (先编译二进制码)

llvm-dis hello.bc  (llvm-dis出来的就是IR)

好像llvm-gcc -S -emit-llvm test.c -o test.ll 也是中间码。 .ll的后缀是中间码

利用objdump可以得到机器码:

objdump -S test.o (这里的-S一定是大写)

 

更新:以上命令其实都在绕弯子,果然当时没有吃透。但是也能用。

生成二进制(汇编): llvm-gcc -S test.c -o test   可以增加参数用于生成INTEL格式的汇编。

llvm-dis 可以将llvm二进制码转换为中间码,而llvm-as则是相反的。

当利用 llvm-gcc -c -emit-llvm test.c -o test生成test之后,可以利用llvm-dis转换为中间码。

    

下面放一个例子:

源代码test2.c:

int func(int a,int b){
    char var[128]="A";
    a=0x4455;
    b=0x6677;
    return a+b;
}
int main(){
    func(0x8899,0x1100);
    return 0;
}


中间码IR:

; ModuleID = 'test2.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-f128:128:128-n8:16:32"
target triple = "i386-pc-linux-gnu"

@.str = private unnamed_addr constant [128 x i8] c"A\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 1

define i32 @func(i32 %a, i32 %b) nounwind {
entry:
  %a_addr = alloca i32, align 4
  %b_addr = alloca i32, align 4
  %retval = alloca i32
  %0 = alloca i32
  %var = alloca [128 x i8]
  %"alloca point" = bitcast i32 0 to i32
  store i32 %a, i32* %a_addr
  store i32 %b, i32* %b_addr
  %var1 = bitcast [128 x i8]* %var to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %var1, i8* getelementptr inbounds ([128 x i8]* @.str, i32 0, i32 0), i32 128, i32 1, i1 false)
  store i32 17493, i32* %a_addr, align 4
  store i32 26231, i32* %b_addr, align 4
  %1 = load i32* %a_addr, align 4
  %2 = load i32* %b_addr, align 4
  %3 = add nsw i32 %1, %2
  store i32 %3, i32* %0, align 4
  %4 = load i32* %0, align 4
  store i32 %4, i32* %retval, align 4
  br label %return

return:                                           ; preds = %entry
  %retval2 = load i32* %retval
  ret i32 %retval2
}

declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind

define i32 @main() nounwind {
entry:
  %retval = alloca i32
  %0 = alloca i32
  %"alloca point" = bitcast i32 0 to i32
  %1 = call i32 @func(i32 34969, i32 4352) nounwind
  store i32 0, i32* %0, align 4
  %2 = load i32* %0, align 4
  store i32 %2, i32* %retval, align 4
  br label %return

return:                                           ; preds = %entry
  %retval1 = load i32* %retval
  ret i32 %retval1
}
View Code


汇编码:

test2.o:     文件格式 elf32-i386


Disassembly of section .text:

00000000 <func>:
   0:    55                       push   %ebp
   1:    89 e5                    mov    %esp,%ebp
   3:    81 ec a8 00 00 00        sub    $0xa8,%esp
   9:    8b 45 0c                 mov    0xc(%ebp),%eax
   c:    8b 4d 08                 mov    0x8(%ebp),%ecx
   f:    8d 95 70 ff ff ff        lea    -0x90(%ebp),%edx
  15:    89 4d fc                 mov    %ecx,-0x4(%ebp)
  18:    89 45 f8                 mov    %eax,-0x8(%ebp)
  1b:    89 e0                    mov    %esp,%eax
  1d:    89 10                    mov    %edx,(%eax)
  1f:    c7 40 08 80 00 00 00     movl   $0x80,0x8(%eax)
  26:    c7 40 04 00 00 00 00     movl   $0x0,0x4(%eax)
  2d:    e8 fc ff ff ff           call   2e <func+0x2e>
  32:    c7 45 fc 55 44 00 00     movl   $0x4455,-0x4(%ebp)
  39:    c7 45 f8 77 66 00 00     movl   $0x6677,-0x8(%ebp)
  40:    8b 45 fc                 mov    -0x4(%ebp),%eax
  43:    03 45 f8                 add    -0x8(%ebp),%eax
  46:    89 45 f0                 mov    %eax,-0x10(%ebp)
  49:    8b 45 f0                 mov    -0x10(%ebp),%eax
  4c:    89 45 f4                 mov    %eax,-0xc(%ebp)
  4f:    8b 45 f4                 mov    -0xc(%ebp),%eax
  52:    81 c4 a8 00 00 00        add    $0xa8,%esp
  58:    5d                       pop    %ebp
  59:    c3                       ret    
  5a:    8d b6 00 00 00 00        lea    0x0(%esi),%esi

00000060 <main>:
  60:    55                       push   %ebp
  61:    89 e5                    mov    %esp,%ebp
  63:    83 ec 28                 sub    $0x28,%esp
  66:    b8 99 88 00 00           mov    $0x8899,%eax
  6b:    b9 00 11 00 00           mov    $0x1100,%ecx
  70:    c7 04 24 99 88 00 00     movl   $0x8899,(%esp)
  77:    c7 44 24 04 00 11 00     movl   $0x1100,0x4(%esp)
  7e:    00 
  7f:    89 45 f4                 mov    %eax,-0xc(%ebp)
  82:    89 4d f0                 mov    %ecx,-0x10(%ebp)
  85:    e8 fc ff ff ff           call   86 <main+0x26>
  8a:    c7 45 f8 00 00 00 00     movl   $0x0,-0x8(%ebp)
  91:    8b 4d f8                 mov    -0x8(%ebp),%ecx
  94:    89 4d fc                 mov    %ecx,-0x4(%ebp)
  97:    89 45 ec                 mov    %eax,-0x14(%ebp)
  9a:    8b 45 fc                 mov    -0x4(%ebp),%eax
  9d:    83 c4 28                 add    $0x28,%esp
  a0:    5d                       pop    %ebp
  a1:    c3                       ret    
View Code

 

posted @ 2014-10-27 12:55  上官筱儿  阅读(9286)  评论(0编辑  收藏  举报