汇编学习(7)——指令汇总

文章目录

  • 指令汇总
    • 简单传送指令
      • mov 传送
      • xchg 交换
    • 加减指令
      • add 简单加法
      • sub 简单减法
      • adc 带进位加法
      • sbb 带进位减法
      • inc 自增
      • dec 自减
      • neg 取反
    • 乘除指令
      • mul 无符号乘法
      • imul 有符号乘法
      • div 无符号除法
      • idiv 有符号除法
    • 符号扩展指令
      • cbw 字节扩展为字
      • cwd 字扩展为双字
      • cdq 双字扩展为四字
      • cwde 另一条字转换为双字指令
    • 扩展传送指令
      • movsx 符号扩展传送
      • movzx 零扩展传送
    • 逻辑运算指令
      • not 否运算
      • and 与运算
      • or 或运算
      • xor 异或运算
      • test 测试指令
    • 移位指令
      • sal/shl/sar/shr 一般移位
      • rol/ror/rcl/rcr 循环移位
      • shld/shrd 双精度移位
    • 状态标志操作指令
      • clc/cld... 复位
      • stc/std... 置位
      • cmc... 标志位取反
      • lahf 取所有标志到ah
      • sahf 置所有标志为ah
    • 跳转指令
      • jcc 条件跳转
      • jmp 无条件跳转
    • 过程调用和返回指令
      • call 过程调用
      • ret 过程返回
    • 比较指令
      • cmp 比较
    • 循环指令
      • loop
      • loope/loopz
      • loopne/loopnz
      • jecxz/jcxz
    • 字符串操作指令
      • lodsb/lodsw/lodsd 字符串装入
      • stosb/stosw/stosd 字符串存储
      • movsb/movsw/movsd 字符串传送
      • scasb/scasw/scasd 字符串扫描
      • cmpsb/cmpsw/cmpsd 字符串比较
      • rep/repz/repe/repnz/repne 重复前缀
    • 位操作指令
      • bt/btc/btr/bts 位测试
      • bsf/bsr 位扫描
    • 条件设置指令
      • setcc 条件设置
    • 堆栈操作指令
      • push 入栈
      • pop 出栈
      • pusha 全入栈(16位)
      • popa 全出栈(16位)
      • pushad 全入栈(32位)
      • popad 全出栈(32位)

指令汇总

简单传送指令

mov 传送

MOV DST,SRC

DST ← SRC

把一个字节、一个字或者一个双字,从源SRC送到目标DST

源和目标不能同时是存储单元

xchg 交换

XCHG OPRD1,OPRD2

OPRD1 ←→ OPRD2

操作数OPRD1的内容与操作数OPRD2的内容交换

源和目标不能同时是存储单元

加减指令

add 简单加法

ADD DST,SRC

DST ← DST + SRC

把目标DST和源SRC相加,结果送到目标DST

sub 简单减法

SUB DST,SRC

DST ← DST - SRC

把目标DST减去源SRC,结果送到目标DST

adc 带进位加法

ADC DST,SRC

DST ← DST + SRC+ CF

把目标DST、源SRC和进位标志CF相加,结果送到目标DST

sbb 带进位减法

SBB DST,SRC

DST ← DST – (SRC+ CF)

把目标DST减去源SRC和借位标志CF,结果送到目标DST

inc 自增

INC DST

DST ← DST + 1

对操作数DST加1,然后把结果送回DST

dec 自减

DEC DST

DST ← DST - 1

对操作数DST减1,然后把结果送回DST

neg 取反

NEG OPRD

OPRD ← 0 - OPRD

取得操作数的相反数(补码表示),结果送回OPRD

乘除指令

mul 无符号乘法

MUL OPRD

指令实现两个无符号操作数的乘法运算

乘数是OPRD,被乘数位于AL、AX或EAX中(由OPRD的尺寸决定,乘数和被乘数的尺寸一致)

乘积尺寸翻倍:16位乘积送到AX;32位乘积送DX:AX;64位乘积送EDX:EAX

操作数OPRD可以是通用寄存器,可以是存储单元,但不能是立即数

imul 有符号乘法

  1. IMUL OPRD

    被乘数和乘数均作为有符号数,其他与mul类似

  2. IMUL DEST,SRC

    DEST <= DEST * SRC

    目的操作数DEST只能是16位或者32位通用寄存器

    源操作数SRC可以是通用寄存器或存储单元(须与目的操作数尺寸一致),可以是一个立即数(尺寸不能超过目的操作数)

  3. IMUL DEST,SRC1,SRC2

    DEST <= SRC1 * SRC2

    目的操作数DEST只能是16位或32位通用寄存器

    源操作数SRC1可以是通用寄存器或存储单元(须与目的操作数尺寸一致),但不能是立即数

    源操作数SRC2只能是一个立即数(尺寸不能超过目的操作数)

div 无符号除法

DIV OPRD

指令实现两个无符号操作数的除法运算

除数是OPRD。被除数位于AX、DX:AX或EDX:EAX中(由OPRD的尺寸决定,被除数的尺寸翻倍)

商在AL、AX或者EAX中;余数在AH、DX或者EDX中(商和余数的尺寸与oprd相同)

操作数OPRD可以是通用寄存器,可以是存储单元,但不能是立即数

必须防止除溢出

idiv 有符号除法

IDIV OPRD

指令实现两个有符号操作数的除法运算

符号扩展指令

cbw 字节扩展为字

CBW

把AL中的符号扩展到AH

cwd 字扩展为双字

CWD

把AX中的符号扩展到DX

cdq 双字扩展为四字

CDQ

把EAX中的符号扩展到EDX

cwde 另一条字转换为双字指令

CWDE

把AX中的符号扩展到EAX的高16位

扩展传送指令

movsx 符号扩展传送

MOVSX DEST,SRC

把源操作数SRC符号扩展后送至目的操作数DEST

源操作数SRC可以是通用寄存器或存储单元,而目的操作数DEST只能是通用寄存器

目的操作数的尺寸必须大于源操作数的尺寸。源操作数的尺寸可以是8位或者16位;目的操作数的尺寸可以是16位或者32位

movzx 零扩展传送

MOVZX DEST,SRC

把源操作数SRC零扩展后送至目的操作数DEST

源操作数SRC可以是通用寄存器或存储单元,而目的操作数DEST只能是通用寄存器

源操作数的尺寸可以是8位或者16位;目的操作数的尺寸只可以是16位或者32位

逻辑运算指令

通用说明:

  • 只有通用寄存器或存储单元可作为目的操作数,用于存放运算结果
  • 如只有一个操作数,则该操作数既是源又是目的
  • 如有两个操作数,那么最多只能有一个是存储单元,源操作数可以是立即数
  • 存储单元可采用各种存储器操作数寻址方式
  • 操作数可以是字节、字或者双字。如果有两个操作数,尺寸必须一致

not 否运算

NOT OPRD

把操作数OPRD按位“取反”,然后送回OPRD

and 与运算

AND DEST,SRC

对两个操作数进行按位的逻辑“与”运算,结果送到目的操作数DEST

or 或运算

OR DEST,SRC

对两个操作数进行按位的逻辑“或”运算,结果送到目的操作数DEST

xor 异或运算

XOR DEST,SRC

对两个操作数进行按位的逻辑“异或”运算,结果送到目的操作数DEST

test 测试指令

TEST DEST,SRC

类似指令AND,把两个操作数进行按位“与”,但结果不送到目的操作数DEST,仅仅影响状态标志

移位指令

sal/shl/sar/shr 一般移位

算术左移指令 SAL(Shift Arithmetic Left)

逻辑左移指令 SHL(SHift logic Left)

算术右移指令 SAR(Shift Arithmetic Right)

逻辑右移指令 SHR(SHift logic Right)

SAL OPRD,count

SHL OPRD,count

SAR OPRD,count

SHR OPRD,count

操作数OPRD可以是通用寄存器或存储器单元,尺寸可以是字节、字或者双字

count表示移位的位数,可以是一个8位立即数,可以是寄存器CL。寄存器CL表示移位数由CL的值决定

通过截取count的低5位,实际的移位数被限于0到31之间

rol/ror/rcl/rcr 循环移位

左循环移位指令 ROL(ROtate Left)

右循环移位指令 ROR(ROtate Right)

带进位左循环移位指令 RCL(Rotate Left through CF)

带进位右循环移位指令 RCR(Rotate Right through CF)

ROL OPRD,count

ROR OPRD,count

RCL OPRD,count

RCR OPRD,count

操作数OPRD可以是通用寄存器或存储器单元,尺寸可以是字节、字或者双字

count表示移位的位数,可以是一个8位立即数,可以是寄存器CL。寄存器CL表示移位数由CL的值决定

通过截取count的低5位,实际的移位数被限于0到31之间

shld/shrd 双精度移位

SHLD OPRD1,OPRD2,count

SHRD OPRD1,OPRD2,count

操作数OPRD1作为目的操作数,可以是通用寄存器或者存储器单元,尺寸是字或者双字

操作数OPRD2相当于源操作数,只能寄存器,尺寸必须与操作数OPRD1一致

count表示移位的位数,可以是一个8位立即数,也可以是寄存器CL。寄存器CL表示移位数由CL的值决定。

通过截取count的低5位,移位数被限于0到31之间

状态标志操作指令

clc/cld… 复位

对应标志位复位为0

stc/std… 置位

对应标志位置位为1

cmc… 标志位取反

对应标志位取反

lahf 取所有标志到ah

将eflags低8位送至ah中

sahf 置所有标志为ah

使得eflags低8位为ah的值

跳转指令

jcc 条件跳转

Jcc LABEL

符号cc表示各种条件缩写,LABEL代表源程序中的标号

当条件满足时,转移到标号LABEL处;否则继续顺序执行

jmp 无条件跳转

JMP LABEL

指令使控制无条件地转移到标号LABEL位置处

所谓无条件是指没有任何前提,肯定实施转移

过程调用和返回指令

call 过程调用

CALL LABEL

  • LABEL可以是程序中的一个标号,也可以是一个过程名
  • 段内直接调用指令进行如下具体操作:
    • 把返回地址偏移(EIP内容)压入堆栈
    • 使得EIP之内容为目标地址偏移,从而实现转移
  • 与无条件转移指令相比,过程调用指令CALL只是多了保存返回地址的步骤

ret 过程返回

RET

该指令从堆栈弹出返回地址,送到指令指针寄存器EIP

通常,这个返回地址就是在执行对应的调用指令时所压入堆栈的返回地址

RET count

额外调整ESP。把count加到ESP,常用于平衡在调用子程序时压入堆栈的参数

比较指令

cmp 比较

CMP DEST,SRC

根据DEST–SRC的差影响标志寄存器中的各状态标志,但不把作为结果的差值送的目的操作数DEST(即不把结果送到目的操作数的sub指令)

循环指令

loop

LOOP LABEL

使寄存器ECX的值减1,如果结果不等于0,则转移到标号LABEL处,否则顺序执行LOOP指令后的指令

loope/loopz

LOOPE LABEL

LOOPZ LABEL

使寄存器ECX的值减1,如果结果不等于0,并且零标志ZF等于1(表示相等),则转移到标号LABEL处,否则顺序执行

指令本身实施的ECX减1操作不影响标志

loopne/loopnz

LOOPNE LABEL

LOOPNZ LABEL

使寄存器ECX的值减1,如果结果不等于0,并且零标志ZF等于0(表示不相等),则转移到标号LABEL处,否则顺序执行

指令本身实施的ECX减1操作不影响标志

jecxz/jcxz

JECXZ LABEL

当寄存器ECX的值等于0时转移到标号LABEL处,否则顺序执行

JCXZ LABEL

当寄存器CX的值等于0时转移到标号LABEL处,否则顺序执行

字符串操作指令

通用说明:

  • 变址寄存器ESI指向源串,变址寄存器EDI指向目的串
  • 源操作数,缺省引用数据段寄存器DS;目的操作数,缺省引用附加段寄存器ES
  • DS:ESI指向源串,ES:EDI指向目的串
  • 如果只有一个数据段,或者说源串与目的串在同一个段,那么可以简单地认为,ESI指向源串,EDI指向目的串
  • 操作方向由标志DF决定:
    • DF复位(为0),由低向高,按递增方式调整
    • DF置位(为1),由高向低,按递减方式调整

lodsb/lodsw/lodsd 字符串装入

LODSB ;装入字节(Byte)

LODSW ;装入字(Word)

LODSD ;装入双字(Double Word)

字符串装入指令把字符串中的一个字符装入到累加器中

字符是字节、字、双字,对应累加器是AL、AX、EAX

根据字符尺寸,和方向标志DF,调整指向字符串的指针

stosb/stosw/stosd 字符串存储

STOSB ;存储字节(Byte)

STOSW ;存储字(Word)

STOSD ;存储双字(Double Word)

字符串存储指令把累加器的值存到字符串中,即替换字符串中一个字符。

字符是字节、字、双字,对应累加器是AL、AX、EAX

根据字符尺寸,和方向标志DF,调整指向字符串的指针

movsb/movsw/movsd 字符串传送

MOVSB ;字节传送

MOVSW ;字传送

MOVSD ;双字传送

字节传送指令MOVSB把寄存器ESI所指向的一个字节数据传送到由寄存器EDI所指向的存储单元中,然后根据方向标志DF复位或置位使ESI和EDI之值分别增1或减1

scasb/scasw/scasd 字符串扫描

SCASB ;串字节扫描

SCASW ;串字扫描

SCASD ;串双字扫描

串字节扫描指令SCASB把累加器AL的内容与由寄存器EDI所指向一个字节目标数据采用相减方式比较,相减结果反映到各状态标志(CF,ZF,OF,SF,PF和AF),但不影响两个操作数,然后根据方向标志DF复位或置位使EDI之值增1或减1

cmpsb/cmpsw/cmpsd 字符串比较

CMPSB ;串字节比较

CMPSW ;串字比较

CMPSD ;串双字比较

串字节比较指令CMPSB把寄存器ESI所指向的一个字节源数据与由寄存器EDI所指向的一个字节目标数据采用相减方式比较,相减结果反映到各有关标志(CF,ZF,OF,SF,PF和AF),但不影响两个操作数,然后根据方向标志DF复位或置位使ESI和EDI之值分别增1或减1。

rep/repz/repe/repnz/repne 重复前缀

  • REP

    每一次重复先判断ECX是否为0,如为0就结束重复,否则ECX的值减1,重复其后的串操作指令

  • REPZ/REPE

    每一次重复先判断ECX是否为0,如ECX为0或串操作指令使零标志ZF为0,结束重复,否则ECX的值减1,重复其后的串操作指令

  • REPNZ/REPNE

    每一次重复先判断ECX是否为0,如ECX为0或串操作指令使零标志ZF为1,结束重复,否则ECX的值减1,重复其后的串操作指令

位操作指令

bt/btc/btr/bts 位测试

通用说明:

  • 操作数OPRD1指定位串,可以是16位或32位通用寄存器,可以是16位或32位存储单元地址
  • 操作数OPRD2指定位号,可以是操作数OPRD1尺寸相同的通用寄存器,也可以是8位立即数

BT OPRD1,OPRD2 ;位测试

位测试指令BT,把被测试位的值送到进位标志CF

BTC OPRD1,OPRD2 ;位测试并取反

位测试并取反指令BTC,把被测试位的值送到进位标志CF,并且把被测试位取反

BTR OPRD1,OPRD2 ;位测试并复位

位测试并复位指令BTR,把被测试位的值送到进位标志CF,并且把被测试位复位,也即清0

BTS OPRD1,OPRD2 ;位测试并置位

位测试并置位指令BTS,把被测试位的值送到进位标志CF,并且把被测试位置位,也即置1

bsf/bsr 位扫描

通用说明:

操作数OPRD1是16或32位通用寄存器,操作数OPRD2可以是16位或32位通用寄存器或者存储单元;但操作数OPRD1和OPRD2的位数(长度)必须相同

BSF OPRD1,OPRD2 ;顺向位扫描

从右向左(位0至位15或位31)扫描字或双字操作数OPRD2中第一个含“1”的位,并把扫描到的第一个含“1”的位的位号送操作数OPRD1

BSR OPRD1,OPRD2 ;逆向位扫描

从左向右(位15或位31至位0)扫描字或双字操作数OPRD2中第一个含“1”的位,并把扫描到的第一个含“1”的位的位号送操作数OPRD1

条件设置指令

setcc 条件设置

SETcc OPRD

当条件满足时,那么将目的操作数OPRD设置成1,否则设置成0

符号cc是代表各种条件的缩写,是指令助记符的一部分;操作数OPRD只能是8位寄存器或者字节存储单元,用于存放设置结果

堆栈操作指令

push 入栈

PUSH SRC

把源操作数SRC压入堆栈

把一个双字数据压入堆栈时,先把ESP减4,然后再把双字数据送到ESP所指示的存储单元

把一个字数据压入堆栈时,先把ESP减2,再把字数据送到ESP所指示的存储单元

pop 出栈

POP DEST

从栈顶弹出一个双字或者字数据到目的操作数DEST

出栈指令操作数不可以是立即数,也不能是代码段寄存器CS

从栈顶弹出一个双字数据时,先从ESP所指示的存储单元中取出一个双字送到目的操作数,然后把ESP加4

从栈顶弹出一个字数据时,先从ESP所指示的存储单元中取出一个字送到目的操作数,然后把ESP加2

pusha 全入栈(16位)

16位通用寄存器全进栈指令

入栈顺序AX、CX、DX、BX、SP、BP、SI、DI

popa 全出栈(16位)

16位通用寄存器全出栈指令

出栈顺序与入栈顺序相反

pushad 全入栈(32位)

32位通用寄存器全进栈指令

EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI

popad 全出栈(32位)

32位通用寄存器全出栈指令

出栈顺序与入栈顺序相反

你可能感兴趣的:(汇编)