程序的机器级表示

程序的机器级表示

  • x86-64 汇编(AT&T 语法)
    • 数据类型
      • 整数按照长度分类:
        • 1 字节:b
        • 2 字节:字,w
        • 4 字节:双字,l
        • 8 字节:四字,q
      • 浮点数按照长度分类:
        • 4 字节:单精度
        • 8 字节:双精度
        • 10 字节
    • 通用寄存器
      • 命名规则:
        • 用前缀来区分寄存器的不同长度:
          • 无前缀:16 位
          • e:32 位
          • r:64 位
        • 用后缀来区分寄存器中的不同部分:
          • l:低 8 位(仅 abcd 16 位寄存器)
          • h:高 8 位(仅 abcd 16 位寄存器)
          • d:低 32 位(仅 %r8~%r15
          • 其他: 所有部分
      • 通用寄存器名称及作用:
        • %rax:累加结果
        • %rbx:基址
        • %rcx:计数器
        • %rdx:数据
        • %rsi:源索引
        • %rdi:目标索引
        • %rsp:栈指针
        • %rbp:基址指针
        • %r8~%r15:64 位通用寄存器,没有特殊意义
    • 指令
      • 操作数与寻址
        • 多种形式(适用于所有指令):
          • 立即数:相当于常量,硬编码在指令中,以 $ 开头。
          • 寄存器
          • 内存:用 () 表示一个内存单元,括号中间是内存地址。
        • 内存寻址方式:
          • 通用地址计算形式:<C>(<Rb>, <Ri>, <S>),表示地址 <C> + <Rb> + <S> * <Ri>
          • 简单寻址:(<Rb>)
          • 变址:<C>(<Rb>)
      • 移动
        • mov?
          • 语法 mov? <S>, <D>,其中 ? 可以是 bwlq,表示把 <S> 的值赋值给 <D>
          • 操作数规则:
            • <S><D> 是操作数,可以是立即数、寄存器、内存。
            • 立即数只表示 32 位有符号整数。
            • <S><D> 不可以同时是内存位置。
          • <D> 为寄存器时的赋值规则:
            • 如果 ?bw,则只修改 <D> 的指定的位置和长度。
            • 如果 ?l,则用 <S> 修改 D 的低 32 位,同时用 0 清空高 32 位。
            • 如果 ?q,则使用全部寄存器空间,没有特殊情况。
        • movabsq
          • 语法 movabsq <S>, <D>,表示移动立即数。
          • <S> 是一个 64 位立即数,其他功能与 mov? 类似。
        • movz??
          • 语法 movz?? <S>, <D>,其中 ? 都可以是 bwlq,表示赋值的时候清零高位(零扩展)。
          • 两个 ? 需要满足 <D> 的比 <S> 更长。?? 不能是 lq,因为这个是 movl 的默认行为。
        • movs??
          • 语法 movz?? <S>, <D>,表示赋值的时候使用符号扩展。
          • 其他与 movz?? 类似,但是存在 movslq
        • c?t?
          • 语法 c?t?,表示对 %ax 类寄存器符号扩展再赋值给自身。
          • cltq 表示符号扩展 %eax,赋值给 %rax
          • cqto 表示符号扩展 %rax,赋值给 %rdx:%rax,即结果的高位在 %rdx
      • 算术/逻辑运算
        • leaq
          • 语法 leaq <C>(<Rb>, <Ri>, <S>), <D>,表示计算地址并赋值给 <D>
          • 寻址计算可以用于表示乘和加,比分开的乘和加更高效。
        • 双目算术/逻辑指令
          • add? <S>, <D>,表示 <D> += <S>
          • sub? <S>, <D>,表示 <D> -= <S>
          • 乘法系列:
            • imul? <S>, <D>,表示补码 <D> *= <S>
            • imulq <S>,表示补码 %rdx:%rax = <S> * %rax
            • mul? <S>, <D>,表示无符号 <D> *= <S>
            • mulq <S>,表示无符号 %rdx:%rax = <S> * %rax
          • 除法系列:
            • idivq <S>,表示补码 %rax = %rdx:%rax / <S>%rdx = %rdx:%rax % <S>
            • divq <S>,表示无符号 %rax = %rdx:%rax / <S>%rdx = %rdx:%rax % <S>
          • and? <S>, <D>,表示 <D> &= <S>
          • or? <S>, <D>,表示 <D> |= <S>
          • xor? <S>, <D>,表示 <D> ^= <S>
          • sal? <S>, <D>,表示 <D> <<= <S>
          • sar? <S>, <D>,表示 <D> >>= <S>,即算术右移。
          • shr? <S>, <D>,表示 <D> >>>= <S>,即逻辑右移。
        • 单目算术/逻辑指令
          • neg? <D>,表示 <D> = -<D>
          • not? <D>,表示 <D> = ~<D>
          • inc? <D>,表示 <D> += 1
          • dec? <D>,表示 <D> -= 1