课前复习

硬件基础

  • 通用寄存器:
    • 8位 : ah,al,ch,cl,dh,dl,bh,bl
    • 16位: ax,cx,dx,bx,sp,bp,si,di
    • 32位: eax,ecx,edx,ebx,esp,ebp,esi,edi
  • 指令指针寄存器: eip
  • 标志寄存器 : eflags
    • 状态标志位
      • CF - 进位标志( 条件: 结果的最高进位被置1)
      • OF - 溢出标志( 条件: 次高位进位 , 再与最高位进行异或,结果为1则置1.)
      • SF - 符号标志(条件: 取结果的最高位作为sf的值)
      • ZF - 零标志(条件: 结果为0则置1)
      • AF - 辅助进位标志
      • PF - 奇偶标志
    • 控制标志位
      • DF - 方向标志(控制串操作的地址是递增,还是递减)
      • IF - 中断允许标志
      • TF - 陷阱标志
  • 内存管理模式
    • 16位 : 分段机制
      • 访问内存的时候使用的是逻辑地址, 物理地址的计算方式 : 段基地址*16 + 段内偏移
      • 访问不同的内存时, 会使用不同的段寄存器来提供段基地址
        • mov ax,[1000h]; 默认使用ds作为段寄存器
        • mov ax,[bp] ; 含有bp栈底指针寄存器时,使用ss作为默认的段寄存器
        • mov ax,[bx]: 默认使用ds作为段寄存器
        • 如果默认的段寄存器是ds,那么这个默认段寄存器可以被修改:mov ax,ss:[1000h]
        • 访问内存时, []内的寄存器的组合是有限的. 只能使用bp,bx,si,di寄存器.
    • 32位 : 使用保护模式机制
      • 段寄存器保存的段选择子
      • 仍然使用分段机制的方式计算地址: 段基地址*16 + 段内偏移 , 但是所有的段基地址都是0 , 所以, 32位模式的内存管理模式也被称为平坦模式.
      • 使用内存操作数时, 在[]内可以使用多种寄存器的组合(参考32位汇编的寻址模式)

指令基础

  1. 指令的组成:
    1. 操作码(助记符)
    2. 操作数
      1. 只有三种类型: 立即数, 寄存器, 内存操作数(使用[]表示)
  2. 指令原型说明符(用于说明指令的操作数可以是什么类型):
    1. imm - 立即数
    2. reg - 寄存器
    3. seg - 段寄存器
    4. mem - 内存操作数.
    5. 大小说明符(决定指令的操作数是什么大小(字节/字/双字))
      1. 8 - 字节(例如:imm8,reg8,mem8)
        1. reg8 表示只能接受大小是8位的寄存器,例如: ah,bh,cl…
        2. mem8表示只能接受大小是8位的内存操作数, 例如: byte ptr [1000], 所以byte ptr是表示内存操作数的大小.
      2. 16 - 2字节的操作数
      3. 32 - 4字节的操作数
  3. 指令的两个操作数, 一般不能同时都是内存操作数.
  4. 算术运算指令:
    1. 加 : add
    2. 减 : sub
    3. 乘 : mul / imul(有符号乘法指令)
    4. 除 : div (也包括了取余)
    5. 自增: inc
    6. 自减 : dec
  5. 位运算
    1. and - 按位与
    2. or - 按位或
    3. xor - 按位异或
    4. not - 按位取反
    5. shl - 左移
    6. shr - 右移
  6. 数据传送指令
    1. mov - 赋值
    2. lea - 取地址
    3. xchg - 交换两个操作数
    4. push - 将数据压入栈,esp被减去和操作数一样的大小
    5. pop - 将数据弹出栈,保存到操作数中,esp被增加和操作数一样的大小
    6. pushf - 将标志寄存器入栈
    7. popf - 将栈顶数值弹出到标志寄存器中
    8. pushad - 将所有通过寄存器压入栈中,顺序: eax,ecx,edx,ebx,esp,ebp,esi,edi
    9. popad - - 将栈中元素弹出到所有的通过寄存器中,弹出顺序和压入顺序相反.

32位的寻址模式

用于确定指令中使用什么操作数.

  1. 立即数寻址
  2. 寄存器寻址
  3. 存储器寻址
    1. 直接寻址
    2. 寄存器间接寻址
    3. 寄存器相对寻址
    4. 基址变址寻址
    5. 相对基址变址寻址
    6. 带比例因子寻址

串操作指令

  1. 重复前缀: rep/repe/repne
    1. 默认操作数: ecx 保存重复的次数
    2. repe/repne 有一个附加条件: zf标志位的值也会影响指令是否继续重复
  2. movs - 串移动指令(相当于memcpy)
  3. stos - 串存入指令(相当于memset)
    1. 默认操作数 : edi
    2. 默认操作数: al/ax/eax
  4. lods - 串取出指令
    1. 默认操作数: esi
    2. 默认操作数: al/ax/eax
    3. 将esi指向的内存取出存入到al/ax/eax中.
  5. cmps - 串比较指令 ( 类似:memcmp)
    1. 默认操作数: edi
    2. 默认操作数: esi
    3. 取esi和edi的值进行比较, 根据比较的结果设置状态标志位. 不保存比较的结果.

控制转移指令

  • loop 循环指定次数
    • 默认操作数: ecx 保存着循环的次数, 每循环一次,ecx就递减1,ecx等于0就不在循环.
  • jmp 无条件转移指令
    • 间接修改eip, 使程序转移到其它位置执行代码
  • call 函数调用指令
    • 调用前, 先将返回地址(call指令的下一条指令)压入栈中
    • 跳转到目标地址
  • ret 函数返回指令
    • 调用时, 将栈顶的值作为返回值弹出到eip
    • eip指向了哪里,就在哪个地方继续执行代码
  • ret 立即数 - 函数返回指令
    • 调用时, 将栈顶的值作为返回值弹出到eip
    • 再将栈顶指针寄存器esp加上立即数
    • 最后走到eip保存的位置继续执行代码

JCC指令(条件跳转指令)

  • 无符号跳转指令
  • 有符号跳转指令
  • 其它指令

程序基础