汇编语言
第一章 基础知识
第二章 语句结构
第三章 指令系统
操作数的寻址方式:(关注SRC的寻址)
① 寄存器寻址 ADD AL,BL
② 立即寻址 MOV AL,68 描述常量而非地址,不能用于DST
③ 存储器寻址 操作数在存储器中,操作数项要描述其存放地址。
i. 直接寻址 MOV AL,DS:[0010H] ;用段名+【常数】直接表示
MOV AX,WORD PTR VAR1 ;用变量名直接表示(段名隐含)
ii. 寄存器间接寻址 以寄存器内容做偏移地址,可用16位寄存器:SI、DI、BX、BP,使用时必须在中括号里面,其中SI、DI、BX默认DS,BP默认SS。
偏移地址=(16位寄存器) ;括号表示是寄存器的内容,即里面的值
MOV AX,[SI]
MOV AL,ES:[DI] ;访问非默认的DS,需要标注段名
MOV BYTE PTR [BX],98H ;间接寻址不描述类型,需要PTR指定访问类型。
iii. 寄存器相对寻址 位移量D+间接寻址里的16位寄存器
D可以是变量名(定义的数组名)也可以是常数
偏移地址=(16位寄存器)+D ;物理地址是偏移地址再加上相应段寄存器的地址即可
MOV AL,[SI+06H]
MOV AL,06H[SI]
MOV AL,[DI+VAR]
MOV AL,VAR[BX]
iv. 基址变址寻址 BX,BP称基址寄存器(BX默认DS,BP默认SS)
SI,DI称变址寄存器(SI源变址寄存器,DI目标变址寄存器)
偏移地址=(基址寄存器)+(变址寄存器)
MOV AL,[BX]+[SI]
MOV AL,[BX+SI] ;两种形式一样
与间接寻址类似,基址变址寻址也要注意访问类型问题和段前缀是否默认!
v. 相对基址变址寻址
偏移地址=(基址寄存器)+(变址寄存器)+ 位移量D
D可以是变量名(定义的数组名)也可以是常数
MOV AL,[BX+SI+06H]
MOV AL,06H[BX][SI]
MOV AL,[BP+DI+VAR]
MOV AL,VAR[BX][DI]
④ 隐含寻址 例如乘法,默认对AX/AL操作
MUL BX
转移地址的寻址:
① 段内直接寻址 转移指令+目标指令标号
转移指令与目标指令在同一个代码段,不改CS,根据目标指令标号改IP即可。
段内直接转移有短近之分,默认为近(16位),短距离转移要加SHORT(8位),短距离转移的指令代码比近距离转移少一个字节。
② 段内间接寻址 转移指令+寄存器/字存储单元
JMP BX ;BX寄存器内容作为转移目标地址
JMP WORD PTR [SI] ;寄存器间接寻址读取数据短一个字作为转移目标地址
③ 段间直接寻址 转移指令+FAR+PTR+目标指令标号
转移指令与目标指令不在同一个代码段,CS和IP都改
④ 段间间接寻址 转移指令+双字类型变量
从主存两个连续字存储单元中获取转移目标地址,低地址的字修改IP,高地址的字修改CS,从而实现段间转移
JMP DWORD PTR [BX]
JMP ADDR ;ADDR定义成双字变量(DD)
3.助记符汇总
操作项:(操作助记符)
DUP:重复分配空间: 重复次数+DUP(?)
数据传送类指令:
MOV数据传送 MOV AX,BX 1.要注意DST和SRC类型一致
2.不能同时采用存储器寻址,可事先转换成寄存器寻址
3.DST不能是CS(IP也不行)
4.段寄存器DS、ES不能MOV进立即数
XCHG互换 XCHG AX,BX 两个通用寄存器可以这样用其他形式需要具体分析
LEA 取偏移地址 LEA SI,ARR1 把偏移地址送DST,
SRC为变量或者标号等同于 MOV SI,OFFSET ARR1
但是未设定BX值时形如MOV SI,OFFSET [BX+6] 是错误的!!
XLAT查表存 XLAT 把BX+AL的值做偏移地址访问数据段,读一个字节数据存入AL,隐含操作数,BX存表首偏移地址,AL存序号
PUSH入栈 PUSH OPR 不能入栈立即数,步骤为1. SP=SP-2 2.(SP)=OPR
OPR必须是字类型,不明确类型的默认为字,可以是CS
POP出栈 POP OPR 步骤为1.OPR=(SP) 2.SP=SP+2
OPR必须是字类型,不能是CS
I/O指令
IN输入 IN AL/AX PORT/DX 直接寻址PORT为8位
间接寻址DX为16位
当PORT超过8位,需要放在DX里面
OUT输出 OUT PORT/DX AL/AX 与IN相同
完整地址传送指令
LDS 段地址送DS,偏移地址送指定的16位寄存器
LES 段地址送ES,偏移地址送指定的16位寄存器
标志传送指令
LAHF 标志寄存器低八位存AH
SAHF AH存标志寄存器低八位
PUSHF 标志寄存器内容入栈
POPF 栈顶出栈并存标志寄存器
运算符:
OFFSET 取偏移地址: OFFSET+变量/标号
SEG 取段地址: SEG+变量/标号
PTR 重新定义类型: 只能用在地址表达式里
新类型(BYTE、WORD、DWORD/NEAR、FAR)+PTR+变量/标号/地址表达式
ADD加法 ADD AX,BX 对所有标志位都有影响,CF记录最高位进位
ADC带进位加法 ADC DX,CX 加的时候同时加上CF
INC 加一 INC AX 不影响CF但是影响其他的状态标志符
SUB减法 SUB AX,BX 对所有标志位都有影响,CF记录最高位的借位
SBB带进位减法 SBB DX,CX 减的时候同时减去CF
DEC减一 DEC AX 不影响CF但是影响其他的状态标志符
CMP比较 CMP AX,BX 进行减法操作,影响全部状态,但是不保存运算结果。
CF=1则AX
逻辑运算符:按位进行
AND 按位与 影响ZF,PF,SF,CF,OF,并对CF和OF清零
OR 按位或 影响ZF,PF,SF,CF,OF,并对CF和OF清零
XOR 按位异或 影响ZF,PF,SF,CF,OF,并对CF和OF清零
NOT 非 不影响FLAGS
TEST 测试 进行AND操作,但是不保存结果
移位操作指令:P61 指令+DST+CNT
逻辑: SHL 补零,移出的进CF 影响CF,OF,ZF,SF,PF
SHR
算术: SAL 补零,移出的进CF(保符号) 影响CF,OF,ZF,SF,PF
SAR 补符号,移出的进CF
循环: ROL 移出的补,同时赋给CF
ROR
带进位:RCL 补CF,移出的进CF
RCR
循环位移只影响CF和OF,对OF影响只在位移次数CNT=1时有效,否则无定义。
CNT=1时若位移前后符号不变,则OF=0,否则OF=1
算术移位作用于有符号数有乘除效果,左移一位等于该数乘上2(前提是OF=0,表示符号位未变,未溢出),右移一位等于该数除以2(移位所得数为商,余数在CF),无符号逻辑运算也有此效果。
串操作:
源串地址:DS:SI 目的串地址:ES:DI
串操作方向由DF状态决定,默认DF=0正向,然后字节/字串指针相应加减1/2。
CLD置正向 串首到串尾,设置DF=0,SI/DI加
STD置反向 串尾到串首,设置DF=1,SI/DI减
串单次的操作:
1.MOVS串传送 源串和目的串地址隐含在SI,DI(以默认的CLD为例)
MOVSB字节串传送 步骤:1. (ES:DI)(DS:SI) 2. SISI+1, DIDI+1
MOVSW字串传送 步骤:1. (ES:DI)(DS:SI) 2. SISI+2, DIDI+2
串传送不影响各种条件标志。
2.CMPS串比较 源串和目的串地址隐含在SI,DI(以默认的CLD为例)
CMPSB字节串比较 步骤:1. (ES:DI)-(DS:SI) 2. SISI+1, DIDI+1
CMPSW字串比较 步骤:1. (ES:DI)-(DS:SI) 2. SISI+2, DIDI+2
串比较会根据减法结果设置各种条件标志。
3.SCAS串搜索 目的串地址隐含在DI(以默认的CLD为例),还隐含AL/AX
SCASB字节串搜索 步骤:1. AL-(ES:DI),若ZF=1搜索成功 2. DIDI+1
SCASW字串搜索 步骤:1. AX-(ES:DI),若ZF=1搜索成功 2. DIDI+2
串搜索会根据减法结果设置各种条件标志。
4.STOS串存数 目的串地址隐含在DI(以默认的CLD为例),还隐含AL/AX
STOSB字节串存数 步骤:1. (ES:DI)AL 2. DIDI+1
STOSW字串存数 步骤:1. (ES:DI)AX 2. DIDI+2
5.LODS串取数 目的串地址隐含在DI(以默认的CLD为例),还隐含AL/AX
LODSB字节串存数 步骤:1. AL(ES:DI) 2. DIDI+1
LODSW字串存数 步骤:1. AX(ES:DI) 2. DIDI+2
串重复前缀:(以CX为计数器,放在单次操作前作为重复前缀)
程序控制,跳转指令:
1.无条件跳转 JMP 这部分跟第三章的2.转移地址寻址相互联系
2.条件跳转 条件标志状态作为检测条件
单个条件标志状态作为检测条件:
JC LABEL CF=1跳LEBEL,否则顺序执行
JNC LABEL CF=0跳LEBEL,否则顺序执行
JZ/JE LABEL ZF=1跳LEBEL,否则顺序执行
JNZ/JNE LABEL ZF=0跳LEBEL,否则顺序执行
JS LABEL SF=1跳LEBEL,否则顺序执行
JNS LABEL SF=0跳LEBEL,否则顺序执行
JO LABEL OF=1跳LEBEL,否则顺序执行
JNO LABEL OF=0跳LEBEL,否则顺序执行
JP/JPE LABEL PF=1跳LEBEL,否则顺序执行
JNP/JPO LABEL PF=0跳LEBEL,否则顺序执行
多个条件标志状态作为检测条件:
无符号数比较:
JA/JNBE LABEL CF=ZF=0 即 >
JAE/JNB LABEL CF=0 即 ≥
JB/JNAE LABEL CF=1 即 <
JBE/JNA LABEL CF=1或ZF=1 即 ≤
有符号数比较:
JG/JNLE LABEL SF=OF且ZF=0 即 >
JG/JNLE LABEL SF=OF 即 ≥
JG/JNLE LABEL SF !=OF 即 <
JG/JNLE LABEL SF!=OF或ZF=1 即 ≤
注意!带条件的跳转只能是段内短距离转移,范围为-128~+127字节,超过了此范围需要改用JMP来跳转!
3.循环指令 LOOP LABEL
等效于:1. DEC CX 2. JNZ LABEL
由此可见,LOOP也是段内短距离转移
补充:
TYPE求类型 TYPE ARRY ARRY是DB类型则为1,DW类型则为2,以此类推
LENGTH 求长度 LENGTH ARRY 实际是求ARRY中最外层DUP的循环次数,默认为1
SIZE 求存储空间 SIZE ARRY SIZE=LENGTHTYPE
举个例子,ARRY DW 5 DUP(?) 则SIZE ARRY求得为52=10
这三个操作项跟OFFSET用法类似。
祝愿期末考试得高分!!
作者按
2021年12月20日星期一初稿