ASM16
处理机控制类指令
这些指令在特定的情况下,必须使用
对标志位进行设置的指令
CLC
STC
CMC
CLD
STD
CLI
STI
对CPU状态进行控制的指令
NOP
CS:
SS:
DS:
ES:
LOCK
HLT
ESC
WAIT
进位标志操作指令
1 2 3
| clc ;复位进位标志:cf=0 stc ;置位进位标志:cf=1 cmc ;求反进位标志:cf=~cf
|
方向标志操作指令
1 2
| cld ;复位方向标志:df=0 std ;置位方向标志:df=1
|
中断标志操作指令
- 在编写中断服务程序时,需要控制可屏蔽中断的允许和禁止
1 2
| cli ;复位中断标志:if=0 sti ;置位中断标志:if=1
|
空操作指令
NOP
不执行任何操作,但占用一个字节存储单元,空耗一个指令执行周期
NOP
常用于程序调试
- 在需要预留指令空间时用
NOP
填充
- 代码空间多余时也可以用
NOP
填充
- 还可以用
NOP
实现软件延时
- 事实上,
NOP
和XCHG AX,AX
的指令代码一样,都是90H
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 31 32
| MyStack segment stack db 256 dup(?) MyStack ends
MyData segment MY_MSG1 db "Hello World1!",0dh,0ah,'$' MY_MSG2 db "Hello World2!",0dh,0ah,'$' MyData ends
MyCode segment MAIN: mov ax,MyData mov ds,ax mov es,ax
;设置标志位 clc ;cf=0 stc ;cf=1 cmc ;cf=~cf cld ;df=0 std ;df=1 cli ;if=0 sti ;if=1
nop ;什么都不干
mov ax,4c00h int 21h
MyCode ends
end MAIN
|
CLC的效果:
STC的效果:
CMC的效果:
NOP:
封锁前缀指令
- 这是一个指令前缀,可放在任何指令前
- 这个前缀使得在这个指令执行时间内,8086处理器的封锁输出引脚有效,即把总线封锁,使别的控制器不能控制总线;直到该指令执行完后,总线封锁自动解除
- 当CPU与其他处理器协同工作时,lock指令可用于避免破坏有用的信息。
1
| lock inc word ptr ds:[1000]
|
暂停指令
- 暂停指令使CPU进入暂停状态,这时CPU不进入任何操作。当CPU发生复位或来自来自外部的中断时,CPU脱离暂停状态
- HLT指令可用于程序中等待中断。当程序中必须等待中断时,可用HLT,而不必用软件死循环。然后,中断使CPU脱离暂停状态,返回执行HLT的下一条指令
等待指令
- 8086利用WAIT指令和测试引脚实现与8087同步运行
- 浮点指令经由8086处理发往8087,并于8086本身的整数指令在同一个指令序列,而8087执行浮点的指令较慢,所以8086必须与8087保持同步
交权指令
1
| ESC 6位立即数,reg/mem ;把浮点指令交给浮点处理器执行
|
- 浮点协处理器8087指令是与8086的整数指令组合在一起的,当8086发现是一条浮点指令时,就利用ESC指令将浮点指令交给8087执行
- 实际编写程序编写程序时,一般采用易于理解的浮点指令助记符格式
1 2
| ESC 6,[SI] ;实数除法指令:FDIV dword ptr [SI] ESC 20H,AL ;整数加法指令:FADD ST(0),ST
|
位操作类指令
- 位操作类指令以二进制位为基本单位进行数据的操作;这是一类常用的指令,都应该特别掌握
- 注意这些指令对标志位的影响
- 逻辑运算指令
AND
OR
XOR
NOT
TEST
- 移位指令
SHL
SHR
SAR
- 循环移位指令
ROL
ROR
RCL
RCR
逻辑运算指令
1 2 3 4 5
| mov ax,-1 and ax,8000h ;某位清0 or ax,1 ;某位置1 xor ax, 0ffffh ;某位取反 not ax
|
位移指令
SHL
(逻辑左移(无符号))
SHR
(逻辑右移(无符号))
SAL
(算术左移(有符号))(同SHL
)
SAR
(算术右移(有符号))
运行结果(若最高位为0则算术右移后也补0)
1 2 3 4
| shl 左移只能为1次 若要为多次 需要先把左移的次数放到cl中如: mov cl,10 shl ax,cl
|
由于执行cl所需要的周期在次数小于4时更大所以左移代码需要多次执行则写多行左移 如:
1 2 3 4
| shl ax,1 shl ax,1 shl ax,1 shl ax,1
|
在高版本(386及486版本)二者执行一次所需的周期数相同 所以使用cl更高效
若最高位为1则算术右移后也补1
循环移位指令
- 将操作数从另一端溢移出的位返回到另一端形成循环,分成不带进位和带进位,分别具有左移或右移操作
- ROL reg/mem,1/CL ; 不带进位循环左移
- ROR reg/mem,1/CL ; 不带进位循环右移
- RCL reg/mem,1/CL ; 带进位循环左移
- RCR reg/mem,1/CL ; 带进位循环右移
循环移位指令对标志的影响
- 按照指令功能设置进位标志CF
- 不影响SF、ZF、PF、AF
- 如果进行一位移动,则按照操作数的最高符号位是否改变,相应设置溢出标志OF:如果移位前的操作数最高位与移位后的操作数最高位不同(有变化),则OF=1;否则OF=0。当移位次数大于1时,OF不确定
当移位次数超过1时要将移位次数存到cl(shl
等同理)
1 2 3 4
| mov cl,8 mov ax,1234h rol ax,cl ror ax,cl
|
1 2 3 4 5
| ;带进位循环移位 32位 mov ax,0ffffh ;低位 mov bx,0ffffh ;高位 shl ax,1 rcl bx,1
|