移位指令 SHL、SHR 、 SAL 、SAR、ROL、ROR、RCL、RCR
* OPR 不能为立即数
* 不影响标志位
SF ZF PF 根据运算结果设置
shift logical(逻辑,添0) arithmetic(算法,为了不变符号)
O(rotate 循环) C(carry)
十进制10和10H 1010 和 0001 0000
循环是R开头,循环是自己转。
逻辑为补充0,算术右移补充的是边上那一位。
带进位的是把CF也连带上了。
如果是1位,可以直接写。如果移动位数大于1时,必须将移动位数放在CL中。
CF根据各指令规定设定,OF位只有当次数=1时才是有效的,否则该位无定义。当CNT=1时,在移位时最高位发生变化,OF=1,否则为0.
循环移位指令: 不影响 SF、ZF、PF、AF
1) lodsb、lodsw:把DS:SI指向的存储单元中的数据装入AL或AX,然后根据DF标志增减SI
(2) stosb、stosw:把AL或AX中的数据装入ES:DI指向的存储单元,然后根据DF标志增减DI
(3) movsb、movsw:把DS:SI指向的存储单元中的数据装入ES:DI指向的存储单元中,然后根据DF标志分别增减SI和DI DF = 0 时用 + ,DF = 1 时用 -
(4) scasb、scasw:把AL或AX中的数据与ES:DI指向的存储单元中的数据相减,影响标志位,然后根据DF标志分别增减SI和DI
(5) cmpsb、cmpsw:把DS:SI指向的存储单元中的数据与ES:DI指向的存储单元中的数据相减,影响标志位,然后根据DF标志分别增减SI和DI
(6) rep:重复其后的串操作指令。重复前先判断CX是否为0,为0就结束重复,否则CX减1,重复其后的串操作指令。主要用在MOVS和STOS前。一般不用在LODS前。
上述指令涉及的寄存器:段寄存器DS和ES、变址寄存器SI和DI、累加器AX、计数器CX
涉及的标志位:DF、AF、CF、OF、PF、SF、ZF
REP MOVS / STOS / LODS 执行操作:
(1) 如 ( CX ) = 0 则退出 REP,否则转 (2)
(2) ( CX ) = ( CX ) - 1
(3) 执行 MOVS / STOS / LODS
(4) 重复 (1) ~ (3)
REP MOVS:将数据段中的整串数据传送到附加段 源串(数据段)→ 目的串(附加段)
(1) 源串首地址(末地址) → SI
(2) 目的串首地址(末地址) → DI
(3) 串长度 → CX
(4) 建立方向标志 ( CLD 使 DF = 0,STD 使 DF = 1 )
data segment
mess1 db ‘personal_computer’
data ends
extra segment
mess2 db 17 dup (?)
extra ends
STOS 存入串指令: STOS DST STOSB (字节)
STOSW (字)
执行操作:
字节操作:( ( DI ) ) ← ( AL ) , ( DI ) ← ( DI ) ± 1
字操作: ( ( DI ) ) ← ( AX ) , ( DI ) ← ( DI ) ± 2
把AL或AX中的数据装入ES:DI指向的存储单元,然后根据DF标志增减DI
例:把附加段中的 10 个字节缓冲区置为 20H
LODS 从串取指令: LODS SRC
LODSB (字节)
LODSW (字)
执行操作:
字节操作:( AL ) ← ( ( SI ) ) , ( SI ) ← ( SI ) ± 1
字操作 :( AX ) ← ( ( SI ) ) , ( SI ) ← ( SI ) ± 2
把DS:SI指向的存储单元中的数据装入AL或AX,然后根据DF标志增减SI
注意:
* LODS 指令一般不与 REP 联用
* 源串一般在数据段中(允许使用段跨越前缀来修改), 目的串必须在附加段中
* 不影响条件标志位
CMPS 串比较指令: CMPS SRC , DST
CMPSB (字节)
CMPSW (字)
(1) ( ( SI ) ) - ( ( DI ) ) 根据比较结果置条件标志位:相等 ZF = 1 不等 ZF = 0
(2) 字节操作:( SI ) ← ( SI ) ± 1 , ( DI ) ← ( DI ) ± 1
字操作: ( SI ) ← ( SI ) ± 2 , ( DI ) ← ( DI ) ± 2
SCAS 串扫描指令: SCAS DST SCASB (字节) SCASW (字)
字节操作:( AL ) - ( ( DI ) ) , ( DI ) ← ( DI ) ± 1
字操作: ( AX ) - ( ( DI ) ) , ( DI ) ← ( DI ) ± 2
mess db ‘COMPUTER’
lea di, mess
mov al, ‘T’
mov cx, 8
cld
repne scasb
(di):相匹配字符的下一个地址
(cx):剩下还未比较的字符个数
控制转移指令:
无条件转移指令:
段内直接短转移:JMP SHORT OPR 执行操作:( IP ) ← ( IP ) + 8 位位移量
段内直接近转移:JMP NEAR PTR OPR 执行操作:( IP ) ← ( IP ) + 16 位位移量
段内间接转移: JMP WORD PTR OPR 执行操作: ( IP ) ← ( EA )
段间直接远转移:JMP FAR PTR OPR 执行操作: ( IP ) ← OPR 的段内偏移地址 ( CS ) ← OPR 所在段的段地址
段间间接转移: JMP DWORD PTR OPR 执行操作: ( IP ) ← ( EA ) ( CS ) ← ( EA + 2 )
* OPR 可用除立即数以外的任何寻址方式
* CNT = 1, SHL OPR , 1 CNT > 1, MOV CL , CNT SHL OPR , CL ; 以 SHL 为例
* 条件标志位: CF = 移入的数值 1 CNT = 1 时,最高有效位的值发生变化
OF= 0 CNT = 1 时,最高有效位的值不变
OF= 1 CNT = 1 时,最高有效位的值发生变化
移位指令: SF、ZF、PF 根据移位结果设置,AF 无定义
循环移位指令: 不影响 SF、ZF、PF、AF
数字的 ASCII 码是一种 非压缩的 BCD 码
十进制调整指令:
DAA 加法的十进制调整指令
DAS 减法的十进制调整指令
AAA 加法的 ASCII 调整指令
AAS 减法的 ASCII 调整指令
AAM 乘法的 ASCII 调整指令
AAD 除法的 ASCII 调整指令
3)新增指令
MOVSX 带符号扩展传送
MOVZX 带零扩展传送
PUSHA / PUSHAD 所有寄存器进栈
POPA / POPAD 所有寄存器出栈
LFS / LGS / LSS 指针送寄存器和 FS / GS / SS
PUSHFD 标志进栈 POPFD 标志出栈
CWDE 字转换为双字
EAX CDQ 双字转换为 4 字 EDX : EAX BSWAP 32 位寄存器的字节次序变反
XADD 交换加
CMPXCHG 比较并交换 ( 486 )
CMPXCHG8B 比较并交换 8 字节 ( Pentium )
BT 位测试
BTS 位测试并置 1
BTR 位测试并置 0
BTC 位测试并变反
BSF 正向位扫描
BSR 反向位扫描
SHLD 双精度左移
SHRD 双精度右移
INSB / INSW / INSD 串输入
OUTSB / OUTSW / OUTSD 串输出
条件设置指令
(1) 根据单个条件标志的值把目的字节置1
SETZ / SETE SETNZ / SETNE
SETS / SETNS SETO / SETNO
SETP / SETPE SETNP / SETPO
SETC / SETB / SETNAE SETNC / SETNB / SETAE
(2) 比较两个无符号数,根据比较结果把目的字节置1
SETB / SETNAE / SETC SETNB / SETAE / SETNC
SETBE / SETNA SETNBE / SETA
(3) 比较两个带符号数,根据比较结果把目的字节置1
SETL / SETNGE SETNL / SETGE
SETLE / SETNG SETNLE / SETG
其他处理机控制指令
BOUND 界限指令
ENTER 建立堆栈帧
LEAVE 释放堆栈帧
特权指令
与cld相对应的指令是std,二者均是用来操作方向标志位DF(Direction Flag)
repe scasb 指令
repe和repne,前者是repeat equal,意思是相等的时候重复,后者是repeat not equal,不等的时候重复。每循环一次cx自动减一
scasb 意思是[AL]-[DI],也就是比较查询DI中是否有AL中的字符,每比较一次dI自动变化,指向上一个或下一个单元。
若di中有x则跳出循环
MOV AL,X
MOV CX,N
REPE SCASB