汇编指令大全

发布时间 2024-01-01 16:08:13作者: jasony_sam

一.基本知识

8位二进制数一个字节,两个字节16位为一个字,32位一个双字,64位一个四字

1.寄存器

四个寄存器AX,BX,CX,DX可用作16位寄存器,用作8位寄存器时记为AH,AL,BH,BL,CH,CL,DH,DL

指针和变址寄存器:SP堆栈指针寄存器,BP基址指针寄存器,SI源变址寄存器,DI目的变址寄存器

段寄存器:CS代码段寄存器。DS数据段寄存器,SS堆栈段寄存器,ES附加段寄存器

控制寄存器:IP指令指针寄存器

FR标志寄存器:

CF:进位标志,产生进位或者借位,CF=1,否则为0

PF:奇偶标志,反映运算结果里“1”的个数,若结果最低8位有偶数1,PF=1,否则PF=0

AF:辅助进位标志,若D3向D4产生进位或者借位,AF=1,否则为0

ZF:零标志,反映运算结果是否为0,是0则ZF=1,否则ZF=0

SF:符号标志,若符号位为1,SF=1(带符号数为负数),否则SF=0

OF:溢出标志,产生溢出,OF=1,否则OF=0。机器判断最高位进位CF和次高位进位是否相同来确定,不同则OF=1,否则OF=0

DF(direction flag):方向标志,用于串处理指令中控制串处理的方向。DF=1时,每次操作后SI,DI自动减量,处理方向由高地址向低地址方向进行。DF=0时,每次操作后SI,DI自动增量,处理方向由低地址向高地址方向进行。

IF:中断允许标志,IF=1为允许响应可屏蔽中断请求,IF=0则禁止

TF:陷阱标志,TF=1时每执行一条用户指令后自动产生陷阱,进入系统的单步中断处理程序。TF=0则连续不断地执行

2.其他基础

D或没后缀为10进制,B为2进制,Q或O为8进制,H为16进制

字符串常量是用单引号或双引号包含的一个字符序列:"ABC"

定义数据

数据类型

BYTE 8位无符号整数 SBYTE 8位有符号整数

WORD 16位无符号整数 SWORD 16位有符号整数

DWORD 32位无符号整数 SDWORD 32位有符号整数

传统数据伪指令

DB(define byte) 8位整数

DW 16位整数

DD 32位整数

.DATA
//标识了程序中包含变量的区域
VAR1 BYTE 'A'
STRING1 BYTE 'Hello',0DH,0AH//每一个字符占一个字节
//ODH是回车符,0AH是换行符

DUP操作符可以重复分配存储空间

ARRAY1 BYTE 20 DUP(?)//20字节,未初始化

$表示当前地址计数器的当前值,也就是当前所使用的存储单元的偏移地址

STRING BYTE "Hello,The World"
STRINGSIZE=($-STRING)
//从$减去STRING的偏移量得SIZE

操作数

imm立即操作数,reg寄存器操作数,mem内存操作数

与数据相关的运算符和伪指令

offset运算符:返回数据标号的偏移量,按字节计算,表示该数据距数据段起始地址的距离,如MOV SI,OFFSET STRING

align伪指令:讲变量的位置按字节,字等边界对齐,格式align 1/2/4

PTR操作符:用来重载操作数的默认尺寸,如MOV PTR [BX],10H,编译器不能分清是把10H存入字单元还是字节单元,所以要用PTR:MOV BYTE PTR [BX],10H/MOV WORD PTR [BX],10H

TYPE操作符:返回按字节计算机的变量单个元素大小,字节为1,字为2,双字是4

LENGTHOF操作符:计算数组中元素的数目

SIZEOF运算符:返回TYPE和LENGTHOF的乘积

LABEL伪指令:允许同一个变量具有不同的属性,而无需分配实际的存储空间

.DATA
VAR16 LABEL WORD
VAR32 DWORD 12345678H
.CODE
MOV AX,VAR16//AX=5678H
MOV EDX,VAR32//EDX=12345678H

段操作符“:”:跟在段寄存器之后,如MOV AX,ES:[BX]

二.寻址方式

1.寻址方式

立即寻址:MOV AL,6H

寄存器寻址:MOV AX,BX

直接寻址:MOV AX,[1000H] (默认段地址为DS)

寄存器间接寻址:MOV AX,[BX/SI/DI] (默认段地址为DS),MOV AX,[BP] (默认段地址为SS),也可以指定段跨越前缀MOV AX,ES:[BX]

寄存器相对寻址:MOV AL,STRING[SI]/[STRING+SI],也可以指定段跨越前缀MOV AX,ES:[STRING+BX]

基址变址寻址:MOV AX,[BX][DI/SI] (默认段地址为DS)

相对基址变址寻址:MOV AX,ARRAY[BX][DI/SI]/[ARRAY+BX+DI/SI]

2.JMP和LOOP指令

JMP:无条件转移目标地址,JMP L

LOOP:将程序块重复执行次数,CX为计数器,执行LOOP时将CX减一,如果CX不等于0则转到LOOP中指示的标号处

AGAIN:
	  ...
	  LOOP AGAIN

3.DOS调用

AH=1H 从标准读入读取一个字符 AL=字符

AH=2H 在标准输出上显示一个字符并将光标前进一个位置 DL=字符ascii值

AX=9H 在标准输出上显示以'$'结尾的字符串 DS:DX=字符串的段/偏移地址

AH=0AH 从标准输入读取缓冲字符数组 DS:DX=输入结构的段/偏移地址

三.数据传送(不影响标志位)

1.传输指令

MOV destination,source

操作数尺寸一样

不能同时为内存

目的操作数不能是CS,EIP,IP

立即操作数不能直接送进段寄存器

MOV reg,reg

MOV mem,reg

MOV reg,mem

MOV mem,imm

MOV reg,imm

(不包括段寄存器)

MOVSX

将源操作数拷贝到目的操作数,并将该值最高位扩展

MOVSX r32,r/m8

MOVSX r32,r/m16

MOVSX r16,r/m8

MOVZX

将源操作数拷贝到目的操作数,并将该值零扩展,仅适用无符号整数

MOVZX r32,r/m8

MOVZX r32,r/m16

MOVZX r16,r/m8

2.栈操作指令

PUSH

对于16位,PUSH会将SP减2,然后将此值高位先进栈,低位后进栈

POP

对于16位,将此值低位先进栈,高位后进栈,然后PUSH会将SP加2

PUSHA,PUSHAD,POPA,POPAD

PUSHA将按下列顺序压入寄存器:AX.CX,DX,BX,SP原始值,BP,SI,DI

PUSHAD为32位通用寄存器

3.交换指令

XCHG指令

XCHG reg,reg

XCHG mem,reg

XCHG reg,mem

XLAT指令

MOV BX,OFFSET TABLE
MOV AL,03H
XLAT

等同于
MOV AL,[BX+AL]

4.地址传送指令

LEA(load effective address)LEA BX,ARRAY

LDS,LES,LFS,LGS,LSS

将源操作数的双字单元分别送入目的寄存器和指定段寄存器,低送入目的,高送入段。

源操作数必须是存储器寻址方式

LDS BX,TABLE

5.标志操作指令

LAHF和SAHF

LAHF将EFLAGS的低位字节拷贝到AH,标志位包括SF,AF,CF和PF(7,6,4,2,0位)

SAHF将AH拷贝到EFLAGS的低位字节

PUSHF,PUSHFD,POPF,POPFD

PUSHF压入16位EFLAGS

标志位操作指令

CLC(clear carry flag) CF清零

STC(set CF) CF置位

CMC(complement CF) CF取反

CLD(clear direction flag) DF清零

STD(set DF) DF置位

CLI(clear interrupt flag) IF清零

STI(set IF) IF置位

6.I/O指令

I/O地址采用独立编址

IN

IN AL,imm8(将地址为操作数的内容送入al)

IN AX,imm8(将地址为操作数的内容送入ax)

IN AX,DX(将DX所指地址的内容送入ax)

OUT

OUT imm8,AL

同理

四.算术计算

1.加法指令

ADD 加法,和放在目的操作数

ADD 带位加法

INC 加1 (不能是段寄存器)

XADD 交换并相加

2.减法指令

SUB 减法,结果放在目的操作数

SBB 带位减法

DEC 减1

NEG 求补

CMP 比较

CMPXCHG 比较并交换

CMPXCHG8B 比较并交换8字节

3.乘法指令

MUL 无符号数乘法

将AL,AX,EAX与源操作数相乘,8位与AL相乘,积存在AX;16位与AX相乘,积存在DX:AX

IMUL 带符号乘法

执行与MUL相同,若16位乘积扩展到AH,32位扩展到DX,OF和CF置1

4.除法指令

DIV 无符号除法

源操作数为8位除数,则16位被除数在AX,商送入AL,余数送入AH;16位,被除数在DX:AX,商送入AX,余数送入DX

IDIV 有符号除法

和DIV一样,影响OF和CF等标志位

CBW(convert byte to word) 扩展到字指令

将AL最高位扩展到AH

CWD 扩展到双字指令

将AX符号位扩展到DX

CDQ

5.BCD码

五.条件处理

1.逻辑运算和比较指令

AND 与

AND reg,reg

AND mem,reg

AND reg,mem

AND mem,imm

AND reg,imm

OR 或

XOR 异或

TEST 与,但不修改操作数

NOT 取反

除NOT不影响标志位,其余操作完CF=0,OF=0,按运算结果设置ZF,SF,PF

2.比较指令

CMP

执行隐含减法,不修改操作数,修改CF,OF,SF,ZF,PF,AF

CMPXCHG 比较并交换

3.条件转移指令

标志位转移

JZ ZF=1

JNZ ZF=0

JC CF=1

JNC CF=0

JO OF=1

JNO OF=0

JS SF=1

JNS SF=0

JP PF=1

JNP PF=0

JE 相等则跳转

JNE 不相等则跳转

JCXZ CX=0则跳转

无符号数比较转移

JA >

JNBE 不<=(和JA等价)

JAE >=

JNB 不<(和JAE等价)

JB <

JNAE 不>=(和JB等价)

JBE <=

JNA 不>(和JBE等价)

有符号数比较转移

A换成G,B换成L

4.条件循环指令

LOOPZ/LOOPE

在ZF=1时CX无符号值大于0循环,不影响任何标志位

LOOPNZ/LOOPNE

在ZF=0时CX无符号值大于0循环,不影响任何标志位

六.位移指令

1.位移操作

SHL(shift logical left) 逻辑左移

最低位用0填充,最高位移入CF

SHL des,cnt

第一个数是目标操作数,第二个是位移位数

SHL reg,imm8

SHL mem,imm8

SHL reg,CL

SHL mem,CL

OF只有在cnt=1时有效,移动后最高位值变化OF=1,否则为0.SF,ZF,PF按结果设置

SHR同理,最高位用0填充,最低位移入CF

SAR(shift arithmetic right) 算术右移

最高位用原来的符号位填充,最低位送入CF

SAL和SHL等价

ROL(rotate left) 循环左移

把最高位同时移入CF和最低位

ROR同理,把最低位同时移入CF和最高位

RCL(rotate left through carry) 带进位的循环左移

把最高位移入CF,再把CF原有内容移入最低位

SHLD(shift left double) 双精度左移

将目的操作数向左移动指定位数,形成的空位由操作数的高位填充,SF,ZF,AF,PF和CF会受到影响

位测试指令

BSF(bit scan forward) 正向位扫描

目的操作数存放源操作数中为1的最低位的位号BSF AX,BX

BSR(bit scan reverse) 逆向位扫描

目的操作数存放源操作数中为1的最高位的位号

BT

目的操作数的第n位拷贝进CF中BT BX,6

BTR

目的操作数的第n位拷贝进CF中BTR BX,6 ,并将第n位清零

BTS

目的操作数的第n位拷贝进CF中BTS BX,6 ,并将第n位置位

BTC

目的操作数的第n位拷贝进CF中BTC BX,6 ,并将第n位取反

七.串操作

1.重复指令

REP CX>0被重复

REPZ,REPE CX>0且ZF=1被重复

REPNZ,REPNE CX>0且ZF=0被重复

REP MOVSB

2.MOVSB,MOVSW,MOVSD

将数据从SI指向的内存位置传送到DI指向的内存位置,分别是字节传送,字传送,双字传送

可以使用REP前缀,DF决定SI,DI增加还是减少

3.STOSB,STOSW,STOSD

将AL/AX/EAX的内容存入DI指向的位置,DF决定DI增加还是减少

4.LODSB,LODSW,LODSD

将数据从SI指向的内存地址取一个字节,字,双字装入AL/AX/EAX

等同于MOV AL,[SI]->INC SI

5.CMPSB,CMPSW,CMPSD

比较SI指向的内存位置操作数与DI指向的内存位置操作数,根据结果设置AF,CF,OF,PF,SF,ZF

此三个指令源操作数在前,目的操作数在后,允许两个操作数同时为存储器操作数

6.SCASB,SCASW,SCASD

将AL/AX/EAX的内容和DI指向的位置的值进行比较,可用于在字符串或者数组中寻找一个数值

,根据结果设置AF,CF,OF,PF,SF,ZF

八.过程

1.过程操作

过程定义

name PROC
...
RET
name ENDP

CALL指令和RET指令

CALL会将下一条指令地址压进堆栈,控制转移到目的地址

RET实现过程执行完返回调用者,从堆栈的栈顶弹出数据作为返回地址,RET imm8 是弹出返回地址后将SP+imm8,以跳过imm8个字节的无用数据