文档状态:编辑....
...
先介绍一下常使用的非标准化的符号
我们应该会常见(ax),((ax))等等
仔细说一下
- 0层括号 取地址
- 1层括号 取数值
- 2曾括号 做指针
粗略划分的话,分为三大类指令,数据传输,操作控制,数据运算
[1]. MOV[一般传送][2]. PUSH/POP[堆栈操作][3]. XCHG(Exchange)[交换][4]. XLAT(Translate)[查表转换][1]. IN[2]. OUT[1]. LEA(Load Effective Address)[2]. LDS(Load pointer using DS)[3]. LES(Load pointer using ES)[1]. LAHF(Load AH from Flags)[2]. SAHF(Store AH into Flags)[3]. PUSHF(Push Flags onto stack)[4]. POPF(Pop Flags off stack)mov dest, src; (src)->(dest)特点
[1]. 即可按字节(byte)传送,亦可按字[word]传送
[2]. 可使用七大寻址方式
[3]. 可以实现以下的传送
|____寄存器<-->(寄存器|存储器)
|____立即数 -->(寄存器|存储器)
|____段寄存器<-->(寄存器|存储器)
注意
[1]. 不可以修改CS的值,即CS不可以作为[目的操作数],[原因]->CS存储的是当前所在段的段地址,一旦修改会造成麻烦.[这样做合法,但容易导致错误,因此不能这么做.]
[2]. 传送立即数时,一定要注意和目的操作数的数据类型进行匹配。尤其是传送到存储器的时候
[3]. 不可以在段寄存器间或内存单元间传送数据
[4]. 不可以修改或读取IP和标志位寄存器的数值,因此有专门的标志位传送指令
[5]. 不可以把立即数直接传送到段寄存器中[拒绝用户自己划分段]
EXTENSION
MOVSX & MOVZX[80386CPU]
POP DESTPUSH SRC[1]. 操作的数据类型长度为16位[8086][2]. push cs合法, pop cs不合法[3]. 栈底在高地址[4]. push压数据由高地址向低地址存放[至于先sp-=2还是先存先pop都是为了方便存储与扔出]
PUSH执行分两步
1. SP = SP - 2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶
2. 将ax中的内容送到 SS:SP 指向的内存单元处,SS:SP 此时指向栈顶

POP见图中

值交换XCHG dest,src寄存器<-->(存储器|寄存器)XCHG BL,DLXCHG AX,SIXCHG COUNT[DI],AX指定内存空间取值[查表转换]数制转换编码系统转换XLAT SRC_TABLE(AL)<--((BX)+(AL))[Step1]. MOV BX, OFFSET SRC_TABLE[Step2]. MOV AL,0AH[Step3]. XLAT SRC_TABLE有的人说,这种效果也可以使用其他指令实现,而且并不比你的这个执行效率差其实这个指令有一个很重要的前提,那就是*表*,没错,这个命令过于工程性,例如ascii码转换输入输出指令注重的是外设与cpu的数据传送,他们都是累加器专用指令.
IN ACC,PORT;(ACC)<--(PORT)从io端口输入数据到累加器port 的使用定义域{8位立即数,16位寄存器DX}ACC8位则读8位,ACC16位则读16位例子
IN AL,DATA;(AL)<--(DATA)//DATA直接寻址,但不需要加'[]'
IN AX,DATA;(AX)<--((DATA)+1:(DATA))
IN AL,BX; (AL)<--((DX))
IN AX,BX; (AX)<--((DX)+1:(DX))
说明
OUT除了数据传输方向与IN相反,规则不变
;使用 PUSH AX ;PROTECT AX PUSH CX ;PROTECT CX PUSHF ;PROTECT Flags CALL TRANS ;CALL PROCEDURE POPF ;RESTORE Flags POP CX ;RESTORE CX POP AX ;RESTORE AX . . .
[注意]
操作数的类型[存储器][寄存器][立即数][段寄存器]操作数的长度[字][字节]副作用[影响Flags][特别说明]:算数运算类指令大都影响标识符寄存器,但是不同指令影响不同
- +&-(SF,ZF,AF,PF,CF,OF)
- INC&DEC(不影响CF[进位标识])
- *(改变CF和OF,但SZAP均不确定)
- /(大部分不确定,见详析)
(dest)<---(dest)+(src)+(cf)S,Z,A,P,ONO CF !!!修改循环程序中的地址INC DL ;8 BIT & REGISTER INC SI ;16 BIT & REGISTER INC BYTE PTR[BX][SI];8 BIT & MEM INC WORD PTR[DI] ;16 BIT & MEM
[ASCII Adjust for Addition]
隐含操作数:[AL]和[AH]MOV AX, 0007H ;(AH)<--00,(AL)<--07 MOV BL, 08H ;(BL)<--08 ADD AL, BL ;(AL)<--0FH AAA ;(AL)<--05H,(AH)<--01H,(CF)=(AF)<--1 AF 表示出现辅助进位
MOV AX,0007H ; MOV BL,08H ; ADD AL,BL ; DAA ;(AL)=15H,(AH)=00H,(AF)<-1,(CF)=0 [CAUTION:] DAA 没有试图去操作 AH,但是 AAA 试图了! 两者都比较关注单字节的运算产生的进位 DAA 对单字节的进位通过 CF 的形式表达出来 AAA 对单字节的进位通过修改 AH 的形式表达出来
减法指令:
- SUB[NORAML Subtraction]
- SBB[Subtraction with Borrow]
- DEC[]
- NEG[]
- CMP[]
- AAS[]
- DAS[]
[目标] 存储器 寄存器[源] 立即数 存储器 寄存器负-负 可能溢出由上面可以看出 有符号数运算影响 OF 无符号数运算影响 CF 但是计算机并不知道是什么数,所以它认为一个数既为有符号数又为无符号数,这并不矛盾!因为值的含义并不重要,我们只是在乎规则!( ⊙ o ⊙ )我是形式主义?
带借位减法
SBB DEST,SRC ;(DEST)<--(DEST)-(SRC)-(CF)[Negate]求补指令
暂时未解决
不能,因为在指令执行期间,执行指令所需的操作数由BIU从相应的内存区域或I\O端口中取出,传送给执行单元EU因为基址寄存器是16位的,所以可以有64k个节,每个节对应一个段基址,且每个段大小为16字节