Intel x86汇编速查笔记

  2 mins to read  


三种内存模式

  • 实模式平面模型
  • 实模式段模型
  • 保护模式平面模型

保护模式平面模型中的寻址

Base + [(Index * Scale) +Disp]

Base:基址,任意的通用寄存器

Index:索引,任意的通用寄存器

Scale:缩放比例/刻度因子,是一个2,4或8的立即数

Disp:偏移量,8,16或32位的立即数

[]相当于C/Cpp中的指针解引int a = *pointer;

lea指令为取址,相当于&

可利用lea指令实现快速算术运算:

;ECX multiplied by 3

;method 1
mov edx,ecx
shl edx,1
add edx,ecx

;method 2
;lea指令仅根据源操作数里的内容完成运算,将结果存入目标数。不接触内存,也不影响标志位
mov edx,ecx
lea edx,[edx*2+edx]

Register

Register作用Sub Register
eax累加,算数逻辑ax,ah,al
ebx基址,数组bx,bh,bl
ecx计数,迭代cx,ch,cl
edx数据,算数dx,dh,dl
esi源索引,数组si
edi目的索引,数组di
esp堆栈,栈顶指针sp
ebp堆栈,栈底指针bp
eip指令,指向next指令ip
eflags标志位,状态控制flags

eflags标志位

部分标志位在保护模式下为操作系统预留,如VIF虚拟中断标志,IOPL I/O特权标志。此处只总结用户标志位

High=>=>=>=>=>=>=>low
OFDFIFTFSFZFAFPFCF
溢出。进位标志被设置时溢出标志一般也会被设置方向。会影响字符串指令。为0目标指针减小,为1增加中断。设置时中断被启用。STI设置,CLI清零陷阱/单步。被设置时,允许调试器通过强制CPU在调用一个中断程序前执行一条指令以实现单步管理符号。运算改变操作数为负号时零。操作的结果为0时被设置辅助进位。只用于BCD码算术运算,已弃用奇偶。为1的二进制位个数为偶数时被设置,为奇数时被清除进位。用于无符号算术运算。STC设置,CLC清零

数据类型

类型bits范围
sdword32-2147483648~+2147483647
dword320~+4294967295
sword16-32768~+32768
word160~+65535
sbyte8-128~+127
byte80~+255

指令

  • add/sub:算术加/减法
  • mov:移动(赋值)
  • adc:进位加法,会操作eflags进位标志
  • and/or/xor:逻辑与/或/异或,二元操作,运算结束将结果替换目标操作数
  • call:调用sub,在移交控制权之前,它会将紧挨着它身后的一条指令地址压入堆栈,从而在call指令结束后控制权能返回原本的程序流下一条指令
  • clc:清除进位标志CF
  • cld:清除方向标志DF
  • cmp:算术比较,二元,目标操作数不受影响,仅设置想关标志位。操作本身等同于从源操作数中减去目标操作数。一般情况下cmp指令后会紧跟一条条件跳转指令
  • inc/dec:递增/递减,不能操作段寄存器,不影响进位标志
  • div:无符号除法,一元操作,被除数为隐式操作数,除数为显示指定。结果的低位有效部分放入EAX,高位有效部分放入EDX,即使没有高位部分,EDX中的寄存器也会被清零。示例
    • div ch ;商位于AL,余数位于AH
    • div bx ;商位于AX,余数位于DX
    • div ecx ;商位于EAX;余数位于EDX
  • mul:无符号除法,同div
  • int/iret:软甲中断/从中断返回,int触发一个位于内存前1024bytes中的256向量之一的软件中断,当一个中断被调用时,标志寄存器与返回地址一起被压入堆栈,IF标志被清零。
  • j*:有条件跳转
跳转指令跳转前提标志位
JA/JNBEif以上CF==0 && ZF==0
JAE/JNBif以上或等于CF==0
JB/JNAEif以下CF==1
JBE/JNAif以下或等于CF==1 || ZF==1
JE/JZif相等ZF==1
JNE/JNZif不相等ZF==0
JG/JNLEif大于ZF==0 && SF==OF
JGE/JNLif大于或等于SF==OF
JL/JNGEif小于SF!=OF
JLE/JNGif小于或等于ZF==1 || SF!=OF
JCif进位标志被设置CF==1
JNCif进位标志未设置CF==0
JOif溢出OF==1
JNOif没有溢出OF==0
JPif偶数PF==1
JNPif奇数PF==0
JSif符号标志位设置SF==1
JNSif符号标志位未设置SF==0
JCXZif CX==0(许多指令以CX作计数寄存器) 
JECXZif ECX==0 
  • jmp:无条件跳转

  • lea:Load Effective Address ,取出源操作数的地址到目的操作数,如lea ebx,eax+edx*4。目标操作数必须是一个寄存器,不能是内存。存储在目标操作数中的地址是内存中的源操作数的第一个字节的地址

  • loop:循环,直到CX/ECX ==0,一元操作符,操作数为指令标签

  • loopnz/loopne:当CX/ECX>0 && ZF==0时循环,一元操作符,同loop

  • loopz/loope:当CX/ECX>0 && ZF==1时循环

  • movs:移动字符串

    movsb		;将[ESI]处的byte赋值到[EDI]
    movsw		;[ESI]字=>[EDI]
    movsd		;[ESI]双字=>[EDI]
    rep movsb		;将从[ESI]处开始的内存区域复制到从[EDI]开始的内存区域,重复CX/ECX次,每次一个字节
    
  • pop:从栈顶弹出元素到操作数中,操作数只能是16bit or 32bits

  • popa/popad:弹出所有16位寄存器/弹出所有32位寄存器,ESP的值不会弹回ESP,而是直接丢弃

  • popf/popfd:弹出栈顶16bits/32bits到eflags寄存器

  • push/pusha/pushad/pushf/pushfd:压入栈

  • ret:从sub中返回

  • rol/ror:循环左移/右移,即12345<<2 => 34512

  • shl/shr:逻辑左移/右移

  • stc:设置进位标志CF

  • std:设置方向标志DF

  • stos:存储字符串,将EAX/AX/AL的值存储到[DI]/[EDI]指定的位置,通过设置ECX,通过req指令实现循环存储,同movs

  • xchg:交换操作数