微机原理与接口技术--西安电子科技大学-笔记二
关于转移地址的寻址方式
段内转移
- 只有IP改变
- 寻址方式
- 段内直接寻址(相对寻址):直接给出转移到的地址,图示,转移位置的IP = 当前IP + DISP
- 8086指令系统中,所有的条件转移指令,只能在段内转移,且转移范围为当前IP为准,+128~-127;可以使用无条件转移指令搭桥,实现二级转移
- 所有的条件转移指令,都是直接寻址。
- 0100H 操作码 DISP(8位)–>导致IP=0100H + 2;
- 段内间接寻址
- MOV BX OFFSET L2;JMP BX;
- 例:若AL = 1,JMP L;
段间转移
数据传送指令
- 除SAHF、POPF指令外,其余传送类指令CPU执行后对6个状态均无影响
- 语法规则(7)
通用传送指令 MOV
- MOV DST,SRC
取有效地址指令 LEA
- LEA REG(16BX\BP\SI\DI),MEM(5种存储器寻址方式的一个存储单元)
- 例子:图 MOV BX,OFFSET DATA1;LEA BX,DATA1;功能一致
取地址指针指令 LDS LES—了解
- LDS REG(16),SRC(MEM)----双字型单元; SRC的地址指针是段地址:相对地址;所以存在在双字型存储单元中
标志传送指令 LAHF SAHF
- LAHF :读F的低八位的数据给AH
- SAHF : 写AH写入F的低八位
数据交换指令 XCHG
- XCHG DST,SRC;
- DST、SRC均 不能为立即数
- 段寄存器不能参加交换
- [p]==>*p
- p==>SI
字节转换指令 XLAT(查表)
- XLAT ;(EA = DS:(BX)+(AL))---->AL;
- 例子
堆栈操作指令 PUSH POP
- PUSH SRC;SRC 不能为立即数
- POP DST
- PUSHF
- POPF
- 必须按字操作
算术运算类指令
- 只要CPU涉及运算,其结果就影响状态标志位
- 段REG不能参加运算
加法指令
- ADD DST,SRC; DST<—(DST)+SRC;CPU根据结果自动设置6个状态;不带借位
- ADC DST,SRC; DST<—(DST+SRC+CF)
- INC ;增1;DST<—(DST)+1;根据结果设置除CF以外的5个标志位
减法指令 SUB
- SUB DST,SRC;DST<—(DST)-(SRC),根据结果自动设置6个状态
- SBB DST,SRC;DST<—(DST)-(SRC)-CF;
- DEC DST;DST<—(DST) - 1;根据结果设置除CF以外的5个标志位
比较指令 CMP
- CMP DST,SRC;(DST)-(SRC);根据差的结果设置6个状态位,除AF其他都是条件状态位
++条件转移指令
- (P63)根据单个条件:CF:JC\JNC 标号;----SF:JS\JNS 标号;----ZF:JZ(JE)\JNZ(JNE) 标号;----PF:JP\JNP 标号;----OF:JO\JOF 标号
- a\b无符号数—相等(E)、高(A)\低(B)
JB/JNAE 标号–等效于JC
JBE/JNA 标号
JA/JNBE 标号
JAE/JNB 标号
- a\b有符号数–相等(E)、大(G)、小(L)
JL/JNGE 标号
JLE/JNG
JG/JNLE
JGE/JNL
求负指令
- NEG DST;DST<—0-(DST);根据差的结果设置6个状态位
- 例子:在存储器BUFFER中,有一个16位的带符号数,求该数的绝对值并放回原来的位置
- 分析题目,提出算法—程序流程图—
- x-0比较—判断—求负—结果存入BUFFER单元
- 条件二分枝程序
;定义DS段
BUFFER DW ?
;定义代码段
START:MOV AX,BUFFER
CMP AX,0
JNS EXIT
NEG AX
MOV BUFFER,AX
EXIT:
乘法指令—有符号(IMUL)和无符号(MUL)
- MUL SRC;乘数,不可以是立即数寻址
- IMUL SRC;
- DST为隐含的(被乘数),以SRC的类型为主,分为字节型和字型
- MUL
- 字节:AL(DST)*SRC---->AX(AH:AL)
- 字:AX(DST)*SRC---->DX:AX
- 指令执行后只影响CF、OF
- 0 0—>AH积无效:AH=0;
- 1 1—>高部有积
- IMUL
- 字节:(AL)*(SRC)----->
- 0 0 —>AH中的积无效,AH的内容是符号位的扩展,符号位是0,则AH都是0
- 1 1 —>高部有效
除法指令—有符号(IDIV)和无符号(DIV)
- DIV SRC
- IDIV SRC
- DIV
- 字节:AX(DST)/(SRC)—商(AL)和余数(AH)
- 字(DX:AX)/(SRC)—商(AX)和余数(DX)
- 除法指令中6个状态位均无定义
- 例子:将存储器BUFFER中的字节型无符号二进制数转换为十进制数,并将结果以分离BCD的形式存入BUFFER2以下单元
(个位数存在低)
;定义DS段
BUFFER1 DB?
BUFFER2 DB 3DUP(?)
;定义代码段
MOV AL,BUFFER1
MOV AH,0;AX
MOV CL,10
DIV CL;(AX)/(CL)
MOV BUFFER2 AH
MOV AH,0
DIV CLD
MOV BUFFER2+1,AH
MOV BUFFER2+2,AL
符号扩展指令 CBW\CWD
- CBW;(AL)---->AX(AH:AL)符号位的扩展
- CWD;(AX)---->DX:AX
- 例子:Y = a*b+c-18
;定义DS段
DATAa a
DATAb b
DATAc c
DATAy DW
cc EQU 18
;定义代码段
MOV AL,DATAa
IMUL DATAb;结果是AX
MOV BX,AX;扩展AX
MOV AL,DATAc
CBW
ADD AX,BX
SUB AX,18
MOV DATAy,AX
BCD调整指令
- '+ - 'BCD数调整—分离和组合—先运算后调整
- ’ * /’ —分离BCD数—先调整后运算
- 加法BCD数调整指令
组合:DAA;对(AL)的调整,加6调整,进位 在CF中
分离(ASII): AAA;图
- 减法BCD数调整指令
组合:DAS
分离:AAS
例3.17;CF进1,已经-100
- 乘法BCD数调整指令 AAM
只能对分离BCD数进行运算
例3.18
AAM是对AX中的结果进行/10运算,AH(商)、AL(余数)
- 除法BCD数调整 AAD
AAD对AX中的BCD数进行运算,(AH*10+AL)---->AX
影响CF\AF\
逻辑运算类指令(5)
1.段寄存器不可以参加计算
与 AND
- AND DST,SRC;DST< ---- ;CF\OF自动清零,AF没定义,正设置其他三个标志位
或 OR
- OR DST,SRC;同上
异或 XOR
- XOR DST、SRC;同上
测试指令 TEST
- TEST DST,SRC;(DST)AND(SRC);同上
- 在不想破环操作数的情况下,测试某些位的值
- 例3.24 3.10(4)(5)
非 NOT
- NOT DST;按位取反;不影响6个状态标志位\
移位类指令(8)
移位指令(4)
逻辑移位
- 左移—*2
SHL DST,CNT(移位次数);
当CNT = 1 时,可以直接写出;
当CNT > 1,用CL给出;所有移位类指令都适用,根据结果设置除AF以外的5个标志位
- 右移
SFR DST,CNT;
溢出给CF
算数移位
- 左移
SAL DST,CNT;
- 右移
SAR DST,CNT;
循环移位(4)
- 结果只影响CF、OF
不带CF
- 左移
ROL
- 右移
ROR
带CF
- 左移
RCL
- 右移
RCR
- 例子
(DX:AX)*16
SHL AX,1
RCL DX,1
标志位控制类指令
转移指令
无条件转移指令(段内和段间)
- JMP\CALL
- 段间转移
段间直接寻址:JMP FAR PTR ABC;汇编成操作码(1字节)+OFFSET ABC(2字节)+SEG ABC(2字节)
段间间接寻址:
;定义DS段
TABLE DD ABC;OFFSET ABC:SEG ABC---->地址指针
;定义代码段1
//JMP TABLE
LEA BX,TABLE
JMP DWORD PTR [BX]
;定义代码段2
ABC:
有条件转移指令(段内)
循环转移指令(段内)
循环控制类
- LOOP 标号;
CX<----(CX)-1;不影响其他状态位
若(CX)!=0;转移到标号
使用在已知循环次数,0为最大,65536
- LOOPZ(LOOPE)
LOOPZ 标号;
CX<—(CX)-1;
若CX != 0 && ZF==1,转移
适合在指令区域查找不同的字符
;定义DS段
STRING DB '11111121'
COUNT EQU $-STRING;计算字符串的长度
;定义代码段
MOV CX,COUNT
MOV SI,-1
L1:INC SI
MOV AL,STRING[SI]
CMP AL,'1';ZE = 1
LOOPZ L1
JZ NOFIND;测ZF说明没找到
- LOOPNZ(LOOPNE)
LOOPNZ 标号;
CX <—(CX)-1
若CX != 0 && ZF==0,转移
适合在指令区域查找相同的字符
- JCXZ
JCXZ 标号;若 CX == 0,转移
适用于刚开始CX为0
汇编语言程序设计
汇编语言设计基础
- 步骤
伪指令
段定义伪指令
段名 SEGMENT [定位类型] [组合类型]['类别'];一个逻辑段开始指令
实体
段名 ENDS;段定义结束伪指令
- SEGMENT与ENDS的段名要一致
- 两者要配对使用
- 段名一旦用SEGMENT定义,段名本身就具有段地址属性
- 段名本身就有OFFSET属性
- 定位类型—告诉汇编程序(MASM.EXE)本段的起始地址–P93表4.1
PAGE(页)型/64
PARA(节)型/16–默认–缺省型
WORD(字)型/2
BYTE(字节)型/无法保证起始地址在16的倍数
- 组合类型—在多模块程序设计中,告诉LINK.EXE(连接程序),重复逻辑段如何连接
STACK型–告诉LINK段为堆栈段
STACK SEGMENT STACK
DB 256 DUP(?)
STACK ENDS
NODE型—缺省型—默认
- 类别
无意义,方便阅读
8086汇编语言程序的完整结构
;定义堆栈
STACK SEGMENT SATCK
DB 256 DUP(?);定义堆栈段,找16可以整除的,SP = 栈底+1
TOP LABEL WORD ;TOP为变量名;TOP 不占用内存位置,获取SP的地址;LABEL伪指令只有地址、类型属性但是不占内存位置
STACK ENDS
;定义数据段
DATA SEGMENT
实体
DATA ENDS
;定义代码段
CODE SEGMENT
ASSM CS:CODE,DS:DATA,ES:DATA;段寻址伪指令,告诉汇编程序段名和段的关系
ASSM SS:STACK;这种关系是承若关系
START:MOV AX,DATA
MOV DS,AX;数据初始化
MOV ES,AX
/* MOV AX,STACK
MOV SS,AX
MOV SP,OFFSET TOP*/相当于STACK的定义
功能段
/* MOV AH,4CH
INT 21H */ DOS系统的操作指令
CODE ENDS
END START(CS:IP)
汇编语言源程序的完整结构
;定义堆栈
STACK SEGMENT SATCK
DB 256 DUP(?);定义堆栈段,找16可以整除的,SP = 栈底+1
TOP LABEL WORD ;TOP为变量名;TOP 不占用内存位置,获取SP的地址;LABEL伪指令只有地址、类型属性但是不占内存位置
STACK ENDS
;定义数据段
DATA SEGMENT
DATA1
ORG 0004H;对准在偶地址
X_BYTE LABEL BYTE//相当于MOV AL,BYTE PTR X_WORD
X_WORD DW 1234H
DATA ENDS
;定义代码段
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA;段寻址伪指令,告诉汇编程序段名和数据段的关系
ASSUME SS:STACK;这种关系是承若关系,并没有初始化
START:MOV AX,DATA;DATA为立即数
MOV DS,AX;数据初始化,这样才把上面的DATA的放在DS段了
MOV ES,AX
/* MOV AX,STACK
MOV SS,AX
MOV SP,OFFSET TOP*/相当于STACK的定义
;功能段
MOV AL,BYTE PTR X_WORD;MOV AL,X_BYTE
/* MOV AH,4CH ;4CH功能号
INT 21H */ ;DOS系统的操作指令,21H中断类型号
CODE ENDS
END START
- EQU和=的区别
4.2自读
说明
避免只讲指令枯燥,讲了点汇编程序设计的内容
上一篇: MacBook终端美化配置