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实现软件延时
  • 事实上,NOPXCHG 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的效果:

image-20241002160618095

STC的效果:

image-20241002160709811

CMC的效果:

image-20241002160740369

NOP:

image-20241002161040839

封锁前缀指令

1
LOCK	;封锁总线
  • 这是一个指令前缀,可放在任何指令前
  • 这个前缀使得在这个指令执行时间内,8086处理器的封锁输出引脚有效,即把总线封锁,使别的控制器不能控制总线;直到该指令执行完后,总线封锁自动解除
  • 当CPU与其他处理器协同工作时,lock指令可用于避免破坏有用的信息。
1
lock inc word ptr ds:[1000]

暂停指令

1
HLT		;进入暂停状态
  • 暂停指令使CPU进入暂停状态,这时CPU不进入任何操作。当CPU发生复位或来自来自外部的中断时,CPU脱离暂停状态
  • HLT指令可用于程序中等待中断。当程序中必须等待中断时,可用HLT,而不必用软件死循环。然后,中断使CPU脱离暂停状态,返回执行HLT的下一条指令

等待指令

1
WAIT	;进入等待状态
  • 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

image-20241002231658006

位移指令

  • SHL(逻辑左移(无符号))
  • SHR(逻辑右移(无符号))
  • SAL(算术左移(有符号))(同SHL
  • SAR(算术右移(有符号))

运行结果(若最高位为0则算术右移后也补0)

image-20241002232024033

1
2
3
4
shl 左移只能为1次
若要为多次 需要先把左移的次数放到cl中如:
mov cl,10
shl ax,cl

image-20241002232405523

由于执行cl所需要的周期在次数小于4时更大所以左移代码需要多次执行则写多行左移 如:

1
2
3
4
shl ax,1
shl ax,1
shl ax,1
shl ax,1

在高版本(386及486版本)二者执行一次所需的周期数相同 所以使用cl更高效

1
2
mov ax,0ffffh
sar ax,1

若最高位为1则算术右移后也补1

image-20240808224544696

循环移位指令

  • 将操作数从另一端溢移出的位返回到另一端形成循环,分成不带进位和带进位,分别具有左移或右移操作
    • ROL reg/mem,1/CL ; 不带进位循环左移
    • ROR reg/mem,1/CL ; 不带进位循环右移
    • RCL reg/mem,1/CL ; 带进位循环左移
    • RCR reg/mem,1/CL ; 带进位循环右移

image-20240808225231796

循环移位指令对标志的影响

  • 按照指令功能设置进位标志CF
  • 不影响SF、ZF、PF、AF
  • 如果进行一位移动,则按照操作数的最高符号位是否改变,相应设置溢出标志OF:如果移位前的操作数最高位与移位后的操作数最高位不同(有变化),则OF=1;否则OF=0。当移位次数大于1时,OF不确定

image-20240808225718510

image-20240808225802320

image-20240808230507028

image-20240808230547697

image-20240808230640347

当移位次数超过1时要将移位次数存到cl(shl等同理)

1
2
3
4
mov cl,8
mov ax,1234h
rol ax,cl
ror ax,cl

image-20240808231005383

1
2
3
4
5
;带进位循环移位 32位
mov ax,0ffffh ;低位
mov bx,0ffffh ;高位
shl ax,1
rcl bx,1

image-20240808231231211