• LLVM从小白到放弃(三) LLVM IR概述与常用指令


    LLVM IR概述

    • 优化是对LLVM IR进行操作:

    什么是LLVM IR

    • LLVM IR 是一门低级语言,语法类似于汇编
    • 任何高级编程语言(如C++)都可以用LLVM IR表示
    • 基于LLVM IR可以很方便地进行代码优化

    LLVM IR的两种表示方法

    • 第一种是人类可以阅读的文本形式,文件后缀为.ll
    • 第二种是易于机器处理的二进制格式,文件后缀为.bc

    LLVM IR结构

    • 源代码被编译为LLVM IR后,具有以下结构:

    LLVM IR结构:模块 Module
    • 一个源代码对应LLVM IR中的一个模块。
    • 头部信息包含程序的目标平台,如X86、ARM等,和一些其他信息。
    • 全局符号包含全局变量、函数的定义与声明。

    LLVM IR结构:函数 Function
    • LLVM IR中的函数表示源代码中的某个函数。
    • 参数,顾名思义为函数的参数。
    • 一个函数由若干基本块组成,其中函数最先执行的基本块为入口块。

    LLVM IR结构:基本块 BasicBlock
    • 一个基本块由若干个指令和标签组成。
    • 正常情况下,基本块的最后一条指令为跳转指令(br或者switch),或返回指令(retn),也叫作终结指令(Terminator Instruction)。
    • PHI指令是一种特殊的指令。

    LLVM IR结构
    • 了解LLVM IR的结构是我们学习代码混淆的基础,举个例子
      • 以函数为基本单位的混淆:控制流平坦化
      • 以基本块为基本单位的混淆:虚假控制流
      • 以指令为基本单位的混淆:指令替代

    LLVM IR常用指令讲解

    • 终结指令 Terminator Instructions

      • ret指令
        • 函数返回指令,对应C/C++中的return。
      • br指令
        • br是“分支”的英文branch的缩写,分为非条件分支和条件分支,对应C/C++的if语句
        • 无条件分支类似有x86汇编中的jmp指令,条件分支类似于x86汇编中的jnz,je等条件跳转指令。
    • 比较指令

      • icmp指令
        • 整数或指针的比较指令
        • 条件cond可以是eq(相等),ne(不相等),ugt(无符号相等)
      • fcmp指令
        • 浮点数的比较指令
        • 条件cond可以是oeq(ordered and equal),ueq(unordered or equal)
      • switch指令
        • 分支指令,可看做是br指令的升级版,支持的分支更多,但使用也更复杂,对应C/C++中的switch。
    • 二元运算 Binary Operations

      • add指令
      • sub指令
      • mul指令
      • udiv指令
        • 无符号整数除法指令
      • sdiv指令
        • 有符号整数除法指令
      • urem指令
        • 无符号整数取余指令
      • srem指令
        • 有符号整数取余指令
    • 按位二元运算 Bitwise Binary Operations

      • shl指令
        • 整数左移操作指令
      • lshr指令
        • 整数右移指令
      • ashr指令
        • 整数算数右移指令
      • and指令
        • 整数按位与运算指令
      • or指令
        • 整数按位或运算指令
      • xor指令
        • 整数按位异或运算指令
    • 内存访问和寻址操作 Memory Access and Addressing Operations

      • alloca指令
        • 内存分配指令,在栈中分配一块空间并获得指向该空间的指针,类似与C/C++中的malloc函数
      • store指令
        • 内存存储指令,向指针指向的内存中存储数据,类似与C/C++中的指针引用后的赋值操作
    • 类型转换操作 Conversion Operations

      • trunc..to指令
        • 截断指令,将一种类型的变量截断为另一种类型的变量。
      • zext..to指令
        • 零扩展指令,将一种类型的变量拓展为另一种类型的变量,高位补0。
      • sext..to指令
        • 符号位拓展指令,通过复制符号位(最高位)将一种类型的变量拓展为另一种类型的变量。
    • 其他操作 Other Operations

      • phi指令:由静态单赋值引起的问题

      • select指令

        • ? : 三元运算符
      • call指令

        • call指令用来调用某个函数,对应C/C++中的函数调用,与x86汇编中的call指令类似。
  • 相关阅读:
    第24课 多线程开发
    第23课 装饰器
    第22课 调用外部程序
    第20课 异常处理
    第19课 习题讲解
    第18课 面向对象
    第17课 调试程序
    第16课 pycharm 使用
    第15课 模块与包
    第14课 再识函数
  • 原文地址:https://www.cnblogs.com/Tu9oh0st/p/16358531.html
Copyright © 2020-2023  润新知