寻址方式
寻址方式 | 操作数地址 | 指令格式举例 |
---|---|---|
立即寻址 | 操作数由指令给出 | MOV DX, 100H |
寄存器寻址 | 操作数在寄存器中 | ADD AX, BX |
直接寻址 | 由指令给出操作数有效地址 | MOV AX, [100] |
寄存器间接寻址 | PA=(DS)*16+(BX) | MOV AX, [BX] |
寄存器相对寻址 | PA=(DS)*16+(BX)+位移量 | MOV AX, MESS[SI] |
基址变址寻址 | PA=(DS)*16+(BX)+(DI) | MOV AX, [BX+DI] |
相对基址变址寻址 | PA=(DS)*16+(BX)+(DI)+位移量 | MOV AX, BUFF[BX+DI] |
汇编语言
常量
整数:二进制B,八进制Q,十进制D或不带,十六进制H
字符串:连续字节单元,每个单元均存放ASCII码,用单引号包括
数据定义
为程序中的数据分配空间并设置内存单元的初始值
- DB 定义字节
- DW 定义字
- DD 定义双字
- DUP 分配一段数据块空间
表达式
算术运算符
+ — * / MOD SHL
逻辑运算符
- AND
- OR
- NOT
- XOR
关系运算符
- EQ
- NE
- LT
- LE
- GT
- GE
分析运算符
- SEG 求段地址
- OFFSET 求偏移地址
- TYPE 求符号名称类型
- LENGTH 求符号名分配项数,只对DUP有效否则为1
- SIZE 求符号名分配字节数,只对DUP有效否则为1
综合运算符
- PTR
伪指令
- 地址计数器伪指令
$
:表示位置计数器的值,为程序下一个所能分配的储存单元的偏移地址 - 地址对准器位指令
ORG
:指出源程序数据块起点,可改变位置计数器的值 - 符号定义位指令
EQU
:给表达式定义一个等价的符号名 - 解除伪指令
PURGE
:解除EQU定义 - 段定义位指令
SEGMENT
: - 简约段定义伪指令
.386
,.DATA
,.CODE
,.STACK
- 过程定义伪指令
PROC...RET ENDP
- 汇编程序结束伪指令
END
指令系统
通用传送指令
- MOV
堆栈操作指令
按字或双字进行,不能按字节进行;后进先出;CS值能直接保存到堆栈,但是堆栈值不能POP到CS
- PUSH
- POP
- PUSHA
- POPA
- POSHAD
- POPAD
交换指令
- XCHG 目的操作数与源操作数不能均为内存单元,IP不能交换
输入输出指令
只能用累加器作为执行过程;直接IO时范围0-255;间接IO时必须用DX;
- IN
- OUT
换码指令
- XLAT 查表转换指令
MOV AL, DS:[BX +AL]
- XLATB
地址传送指令
- LEA 取有效地址
- LDS
- LES
- LSS
- LFS
- LGS
标志传送指令
- LAHF 读标志指令
- SAHF 设置标志指令
- PUSHG 对标志寄存器的推入
- POPF 对标志寄存器的弹出
- PUSHFD
- POPFD
加法指令
- ADD 不带进位加法
- ADC 带进位加法,CF进位标志
- XADD 字节交换加法
- INC 自增1
减法指令
- SUB 不带借位的减法
- SBB 带借位的减法
- DEC 自减1
- NEG 求补
- CMP 比较
- CMPXCHG 比较交换,若相等则把源操作数送到目的操作数,若不相等则把目的操作数送累加器
- CMPXCHG8B
乘法指令
- MUL 无符号乘法
- IMUL 有符号乘法
除法指令
- DIV 无符号除法
- IDIV 有符号除法
类型转换指令
- CBW AL符号位扩展到AH
- CWD AX符号位扩展到DX
- CWDE AX符号位扩展到EAX
- CDQ EAX符号位扩展到EDX
BCD码指令
- AAA
- DAA
- AAS
- DAS
- AAM
- AAD
逻辑指令
- AND 按位与,结果放在目的操作数
- TEST 按位与,结果不保存,影响标志位
- OR 按位或
- XOR 按位异或
- NOT 按位非
移位指令
- SAL 算术左移
- SAR 算术右移
- SHL 逻辑左移
- SHR 逻辑右移
- ROL
- RCL
- ROR
- RCR
- SHLD
- SHRD
串操作指令
- MOVSB
- MOVSW
- REP
- REPE/REPZ
- REPNE/REPNZ
- CMPSB/CMPSW 字符串比较指令
- SCASB/SCASW 字符串检索指令
- LODSB/LODSW 取字符串指令
- STOSB/STOSW 存字符串指令
控制转移指令
- JMP 无条件转移指令
- JZ/JE 结果为0则转移
- JNZ/JNE 结果不位0则转移
- JS 符号标志SF=1则转移
- JNS SF=0则转移
- JO OF=1则转移
- JNO OF=0则转移
- JP 奇偶标志PF=1则转移
JNP PF=0则转移
JB/JNAE 低于,则转移
- JNB/JAE 不低于,则转移
- JBE/JNA 不高于,则转移
JNBE/JA 高于,则转移
JL/JNGE 小于,则转移
- JNL/JGE 不小于,则转移
- JLE/JNG 不大于,则转移
JNLE/JG 大于,则转移
JCXZ CX为0,则转移到
CALL 子程序调用指令
- RET
- LOOP
- INT
IRET
HLT 暂停指令
标志位操作指令:
- STI IF置1
- CLI IF清0
- CLD DF清0
- STD DF置1
- CLC CF清0
- STC CF置1
- CMC CF求反
汇编例程
5个连续字节单元累加
1 | DATA ;定义数据段 |
用查表方法将一个十六进制数转为对应的ASCII码
1 | DATA |
产生n个裴波纳契数数列
1 | DATA |
找出最大数
编一程序,在以BUF为首地址的字节单元中存放了COUNT个无符号数,找出其中最大数送MAX单元。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24DATA
BUF DB 1,2,3,4,5,23,55,88
COUNT EQU $-BUF ;要统计的数有多少个
MAX DB ?
DATA ENDS
CODE
CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET BUF ;得到BUF偏移地址,即第一位
MOV CX,COUNT – 1 ;
MOV AL,[BX] ;第一个数放入AL
LOOP1: INC BX ;偏移地址+1得到第二个数
CMP AL,[BX] ;比较第一个数与第二个数大小
JAE NEXT ;不小于则转移即第一个数大
MOV AL,[BX] ;否则第二个数大,将其加入比较队列
NEXT: DEC CX ;计数器-1
JNZ LOOP1 ;回到LOOP1比较下一个数
MOV MAX,AL ;循环结束后得到最大数在AL里
MOV AH,4CH
INT 21H
CODE ENDS
END START
统计负数和正数的个数
在以BUF为首地址的字节单元中存放了COUNT个字节数据,编一程序分别统计负数和正数的个数送MINUS和PLUSMAX单元。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31DATA
BUF DB 1,-22,3,4,5,23,55,88
COUNT EQU $-BUF ;要比较的数的个数
PLUS DB ? ;正数个数
MINUS DB ? ;负数个数
DATA ENDS
CODE
CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV BL,0 ;存负数个数
MOV DL,0 ;存正数个数
MOV SI,OFFSET BUF ;拿要比较的数组
MOV CX,0
LOOP1: MOV AL,[SI]
CMP AL,0 ;将第一个数与0比较
JGE NEXT0 ;大于等于0则跳转?
INC BL ;负数个数+1
JMP NEXT1 ;跳转到比较下一个数
NEXT0: INC DL ;正数个数+1
NEXT1: INC SI ;比较下一个数
INC CX ;这里没有使用LOOP而是用CX计数
CMP CX,COUNT ;比较了指定个数后跳转结束
JL LOOP1
MOV MINUS,BL
MOV PLUS,DL
MOV AH,4CH
INT 21H
CODE ENDS
END START