教学提示在学习和应用汇编语言进行程序设计时,有一些经常遇到的问题,例如算术运算,
代码转换等,需要掌握第 2 章 2.7 控制转移类指令
控制转移类指令 用于实现分支,循环,
过程等程序结构,是仅次于传送 指令的最常用指令重点掌握,JMP/Jcc/LOOP CALL/RET
INT n/IRET 常用系统功能调用一般了解,LOOPZ/LOOPNZ INTO
控制转移类指令通过 改变 IP( 和 CS)
值,实现程序执行顺序的改变
2.7.1 无条件转移指令
只要执行无条件转移指令 JMP,就使程序转到指定的目标地址处,从目标地址处开始执行那里的指令
操作数 label是要转移到的 目标地址 ( 目的地址,转移地址 )
JMP指令分成 4种类型:
⑴ 段内转移,直接寻址
⑵ 段内转移,间接寻址
⑶ 段间转移,直接寻址
⑷ 段间转移,间接寻址
JMP label ;程序转向 label标号指定的地址
JMP
第 2 章目标地址的寻址方式
直接寻址方式
转移地址象立即数一样,直接在指令的机器代码中,就是直接寻址方式
间接寻址方式
转移地址在寄存器或主存单元中,
就是通过寄存器或存储器的间接寻址方式第 2 章用标号表达用寄存器或存储器操作数表达
JMP
目标地址的范围:段内
段内转移 —— 近转移 ( near)
在当前代码段 64KB范围内转移
( ± 32KB范围 )
不需要更改 CS段地址,只要改变 IP偏移地址
段内转移 —— 短转移 ( short)
转移范围可以用一个字节表达,
在段内- 128~+ 127范围的转移代码段代码段第 2 章
JMP
目标地址的范围:段间
段间转移 —— 远转移 ( far)
从当前代码段跳转到另一个代码段,可以在 1MB范围
需要 更改 CS段地址和 IP偏移地址
目标地址必须用一个 32位数表达,叫做 32位远指针,它就是逻辑地址第 2 章代码段代码段实际编程时,汇编程序会根据目标地址的距离,
自动处理 成短转移,近转移或远转移程序员可用操作符 short,nearptr 或 far ptr 强制
JMP
JMP段内转移,直接寻址
JMP label ; IP←IP+ 位移量
位移量是紧接着 JMP指令后的那条指令的偏移地址,
到目标指令的偏移地址的地址位移
当向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负
jmp again ;转移到 again处继续执行……
again,dec cx ;标号 again的指令……
jmp output ;转向 output……
output,mov result,al ;标号 output的指令第 2 章 实际为相对寻址段内转移,间接寻址
JMP r16/m16 ; IP←r 16/m16
将一个 16位寄存器或主存字单元内容送入 IP
寄存器,作为新的指令指针,但不修改 CS寄存器的内容
jmp ax ; IP←AX
jmp word ptr [2000h] ; IP←[ 2000h]
第 2 章
JMP
段间转移,直接寻址
JMP far ptr label; IP←label 的偏移地址; CS←label 的段地址
将标号所在段的段地址作为新的 CS值,
标号在该段内的偏移地址作为新的 IP值;这样,程序跳转到新的代码段执行
jmp far ptr otherseg;远转移到代码段 2的 otherseg
第 2 章
JMP
段间转移,间接寻址
JMP far ptr mem; IP←[mem],CS←[mem+ 2]
用一个双字存储单元表示要跳转的目标地址 。 这个目标地址存放在主存中连续的两个字单元中的,低位字送 IP寄存器,高位字送
CS寄存器
mov word ptr [bx],0
mov word ptr [bx+2],1500h
JMP far ptr [bx] ;转移到 1500h:0
第 2 章
JMP
2.7.2 条件转移指令
指定的条件 cc如果成立,程序转移到由标号 label指定的目标地址去执行指令;条件不成立,则程序将顺序执行下一条指令
操作数 label是采用短转移,称为相对寻址方式
Jcc
Jcc label;条件满足,发生转移,IP←IP + 8位位移量;条件不满足,顺序执行第 2 章第 2 章 相对寻址方式
Jcc指令的操作数 label是一个标号
一个 8位位移量,表示 Jcc指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移
8位位移量是 相对于 当前 IP的,且距当前
IP地址- 128~+ 127个单元的范围之内,
属于段内短距离转移
Jcc目标地址就采用这种 相对寻址方式
Jcc指令为 2个字节,条件不满足时的顺序执行就是当前指令偏移指针 IP加 2
Jcc
第 2 章 Jcc指令的分类
Jcc指令不影响标志,但要利用标志 ( 表 2.4) 。 根据利用的标志位不同,17条指令分成 4种情况:
⑴ 判断单个标志位状态
⑵ 比较无符号数高低
⑶ 比较有符号数大小
⑷ 判断计数器 CX为 0
Jcc
第 2 章 判断单个标志位状态
这组指令单独判断 5个状态标志之一
⑴ JZ/JE和 JNZ/JNE:利用零标志 ZF,判断结果是否为零 ( 或相等 )
⑵ JS和 JNS:利用符号标志 SF,判断结果是正是负
⑶ JO和 JNO:利用溢出标志 OF,判断结果是否产生溢出
⑷ JP/JPE和 JNP/JPO:利用奇偶标志 PF,判断结果中,1”的个数是偶是奇
⑸ JC/JB/JNAE和 JNC/JNB/JAE:利用进位标志 CF,判断结果是否进位或借位
Jcc
例题 2.39
例题 2.41
例题 2.42
例题 2.43
例题 2.44
第 2 章 比较无符号数高低
无符号数的大小用高 ( Above) 低
( Below) 表示
利用 CF确定高低,利用 ZF标志确定相等 ( Equal)
两数的高低分成 4种关系:
⑴ 低于 ( 不高于等于 ),JB( JNAE)
⑵ 不低于 ( 高于等于 ),JNB( JAE)
⑶ 低于等于 ( 不高于 ),JBE( JNA)
⑷ 不低于等于 ( 高于 ),JNBE( JA)
Jcc
例 2.45a:比较无符号数
cmp ax,bx ;比较 ax和 bx
jnb next ;若 ax≥ bx,转移
xchg ax,bx ;若 ax< bx,交换
next,...
结果,AX保存较大的 无符号数第 2 章 比较有符号数大小
有符号数的大 ( Greater) 小 ( Less)
需要组合 OF,SF标志,并利用 ZF标志确定相等 ( Equal)
两数的大小分成 4种关系:
⑴ 小于 ( 不大于等于 ),JL( JNGE)
⑵ 不小于 ( 大于等于 ),JNL( JGE)
⑶ 小于等于 ( 不大于 ),JLE( JNG)
⑷ 不小于等于 ( 大于 ),JNLE( JG)
Jcc
例 2.45b:比较有符号数
cmp ax,bx ;比较 ax和 bx
jnl next ;若 ax≥ bx,转移
xchg ax,bx ;若 ax< bx,交换
next,...
结果,AX保存较大的 有符号数第 2 章 计数器 CX为 0转移
这是一条较特殊的指令
CX寄存器通常在程序中用做计数器
JCXZ指令用来判断计数是否为 0
JCXZ label; CX= 0,发生转移,IP←IP + 8位位移量; CX≠0,顺序执行判断计数器为 0( 例 2.36)
mov cx,100
again,movsb ;传送一个字节
dec cx ;传送次数减 1
jnz again ;判断传送次数 cx是否为 0;不为 0( ZF=0),则转移;否则,结束第 2 章
mov cx,100
again,jcxz next ;判断传送次数 cx是否为 0
movsb
dec cx
jmp again
next,...
cmp cx,0
jz next
第 2 章 2.7.3 循环指令 ( loop)
循环指令利用 CX计数器自动减 1,
方便实现计数循环的程序结构
label操作数采用相对寻址方式
LOOP label ; CX←CX - 1,; CX≠0,循环到标号 label
LOOPZ label ; CX←CX - 1,; CX≠0 且 ZF= 1,循环到标号 label
LOOPZ label ; CX←CX - 1,; CX≠0 且 ZF= 0,循环到标号 label
例 2.46:记录空格个数
mov cx,count ;设置循环次数
mov si,offset string
xor bx,bx ; bx清 0,用于记录空格数
mov al,20h
again,cmp al,es:[si]
jnz next ; ZF=0,非空格,转移
inc bx ; ZF=1,是空格,个数加 1
next,inc si
loop again;字符个数减 1,不为 0继续循环
dec cx
jnz again
第 2 章 2.7.4 子程序指令
子程序是完成特定功能的一段程序
当主程序 ( 调用程序 ) 需要执行这个功能时,采用 CALL调用指令转移到该子程序的起始处执行
当运行完子程序功能后,采用 RET返回指令回到主程序继续执行演示子程序调用指令
CALL指令分成 4种类型 ( 类似 JMP)
CALL label ;段内调用,直接寻址
CALL r16/m16 ;段内调用,间接寻址
CALL far ptr label ;段间调用,直接寻址
CALL far ptr mem ;段间调用,间接寻址
CALL指令需要保存返回地址:
段内调用 —— 入栈偏移地址 IP
SP←SP - 2,SS:[SP]←IP
段间调用 —— 入栈偏移地址 IP和段地址 CS
SP←SP - 2,SS:[SP]←IP
SP←SP - 2,SS:[SP]←CS
第 2 章
CALL
子程序返回指令
根据段内和段间,有无参数,分成 4种类型
RET ;无参数段内返回
RET i16 ;有参数段内返回
RET ;无参数段间返回
RET i16 ;有参数段间返回
需要弹出 CALL指令压入堆栈的返回地址
段内返回 —— 出栈偏移地址 IP
IP←SS,[SP],SP←SP + 2
段间返回 —— 出栈偏移地址 IP和段地址 CS
IP←SS,[SP],SP←SP + 2
CS←SS,[SP],SP←SP + 2
i16参数的作用
RET
第 2 章例 2.47:子程序;主程序 mov al,0fh ;提供参数 AL
call htoasc ;调用子程序
...;子程序,将 AL低 4位的一位 16进制数 转换 成 ASCII码
htoasc:and al,0fh ;只取 al的低 4位
or al,30h ; al高 4位变成 3
cmp al,39h ;是 0~ 9,还是 0Ah~ 0Fh
jbe htoend
add al,7 ;是 0Ah~ 0Fh,加上 7
htoend:ret ;子程序返回转换原理第 2 章 2.7.5 中断指令
中断 ( Interrupt ) 是又一种改变程序执行顺序的方法
中断具有多种中断类型
中断的指令有 3条:
INTi8 IRET INTO
本节主要掌握类似子程序调用指令的中断调用指令 INT i8,进而学习使用 DOS功能调用第 2 章 中断指令 INT
INT i8;中断调用指令:产生 i8号中断
IRET;中断返回指令:实现中断返回
INTO;溢出中断指令:;若溢出标志 OF=1,产生 4号中断;否则顺序执行第 2 章 2.7.6 系统功能调用
21H号中断是 DOS提供给用户的用于调用系统功能的中断,它有近百个功能供用户选择使用,主要包括设备管理,
目录管理和文件管理三个方面的功能
ROM-BIOS也以中断服务程序的形式,
向程序员提供系统的基本输入输出程序
汇编语言程序设计需要采用系统的各种功能程序
充分利用操作系统提供的资源是程序设计的一个重要方面,需要掌握第 2 章 功能调用的格式通常按照如下 4个步骤进行:
⑴ 在 AH寄存器中设置系统功能调用号
⑵ 在指定寄存器中设置入口参数
⑶ 执行指令 INT 21H( 或 ROM-BIOS的中断向量号 ) 实现中断服务程序的功能调用
⑷ 根据出口参数分析功能调用执行情况输入输出类功能调用
向显示器输出字符
⒈ 字符的输出
⒉ 字符串的输出
从键盘输入数据
⒊ 字符的输入
⒋ 字符串的输入
⒌ 按键的判断裸机汇编语言程序第 2 章第 2 章 字符输出的功能调用
DOS功能调用 INT21H
功能号,AH= 02H
入口参数,DL=字符的 ASCII码
功能:在显示器当前光标位置显示给定的字符,光标右移一个字符位置 。 如按 Ctrl-Break或 Ctrl-C则退出例 2.48:显示问号;在当前显示器光标位置显示一个问号
mov ah,02h ;设置功能号,ah← 02h
mov dl,'?' ;提供入口参数,dl←'?'
int 21h ; DOS功能调用:显示进行字符输出时,当输出响铃字符
( 07H ) 以 及 退 格 ( 08H ),回车
( 0DH) 和换行 ( 0AH) 字符时,该功能调用可以自动识别并能进行相应处理第 2 章 字符输出的功能调用
显示器功能调用 INT 10H
功能号,AH= 0EH
入口参数,AL=字符的 ASCII码
BL=字符的颜色值 ( 图形方式 )
BH=页号 ( 字符方式 )
通常使 BX= 0
功能:将字符按原属性在光标处显示,光标自动移到下一个字符位置第 2 章 字符串输出的功能调用
DOS功能调用 INT21H
功能号,AH= 09H
入口参数:
DS:DX=欲显示字符串在主存中的首地址字符串应以 $( 24H) 结束
功能:在显示器输出指定的字符串
可以输出回车 ( 0DH) 和换行 ( 0AH)
字符产生回车和换行的作用例 2.49:显示字符串
string db 'Hello,Everybody !',0dh,0ah,'$';在数据段定义要显示的字符串
...
mov ah,09h;设置功能号,ah← 09h
mov dx,offset string;提供入口参数,dx← 字符串的偏移地址
int 21h; DOS功能调用:显示第 2 章 字符输入的功能调用
DOS功能调用 INT21H
功能号,AH= 01H
出口参数,AL=字符的 ASCII码
功能:获得按键的 ASCII代码值
调用此功能时,若无键按下,则会一直等待,直到按键后才读取该键值例 2.50:判断按键
getkey,mov ah,01h ;功能号,ah← 01h
int 21h ;功能调用
cmp al,’Y’ ;处理出口参数 al
je yeskey ;是,Y”
cmp al,’N’
je nokey ;是,N”
jne getkey
...
yeskey,...
nokey,...
第 2 章 字符输入的功能调用
键盘功能调用 INT16H
功能号,AH= 0
出口参数,AX=键值代码对于标准 ASCII码按键,AL= ASCII码,
AH=扫描码;
对于扩展按键,AL= 00H,AH=键扩展码;
对于 alt+小键盘数字按键,AL= ASCII码,
AH= 00H
此功能类同 DOS功能 01H,会一直等待按键例 2.51:字符输入输出
mov ah,0 ;键盘功能调用 ( int 16h)
int 16h ; al← 按键的 ASCII码
mov bx,0 ;显示功能调用 ( int 10h)
mov ah,0eh
int 10h ;显示第 2 章 字符串输入的功能调用
DOS功能调用 INT21H
功能号,AH= 0AH
入口参数,DS:DX=缓冲区首地址
执行该功能调用时,用户按键,最后用回车确认
本调用可执行全部标准键盘编辑命令;
用户按回车键结束输入,如按 Ctrl+
Break或 Ctrl+ C则中止关键要定义好缓冲区例 2.52:输入字符串
buffer db 81 ;定义缓冲区;第 1个字节填入可能输入的最大字符数
db 0 ;存放实际输入的字符数
db 81 dup(0) ;存放输入的字符串
...
mov dx,seg buffer;伪指令 seg取得 buffer的段地址
mov ds,dx ;设置数据段 DS
mov dx,offset buffer
mov ah,0ah
int 21h
第 2 章 按键判断的功能调用
DOS功能调用 INT21H
功能号,AH= 0BH
出口参数,AL= 0,当前没有按键;
AL= FFH,当前已经按键 。
功能:仅判断当前是否有按下的键,
设置 AL后退出例 2.53:按任意键继续
..,;提示,按任意键继续,
getkey:mov ah,0bh
int 21h
or al,al ; al= 0?
jz getkey; al= 0,没有按键,继续等待;等同于如下功能调用
mov ah,01h
int 21h
第 2 章 按键判断的功能调用
键盘功能调用 INT16H
功能号,AH= 1
出口参数:若标志 ZF= 1,无键按下;
若 ZF= 0,有键按下,且 AX=键值代码
功能:此子功能仅判断是否按键,设置零位标志 ZF后退出
这两个功能调用都不循环等待按键,
即使有键按下,键盘缓冲区仍然保留键值并且没有被清空,必要时必须用字符输入功能取走键值清空缓冲区第 2 章 2.8 处理机控制类指令
这些指令在特定的情况下,必须使用
对标志位进行设置的指令
CLC STC CMC
CLD STD
CLI STI
对 CPU状态进行控制的指令
NOP CS,SS,DS,ES:
LOCK HLT ESC WAIT
第 2 章 进位标志操作指令
用于任意设置进位标志
CLC ;复位进位标志,CF← 0
STC ;置位进位标志,CF← 1
CMC ;求反进位标志,CF← ~ CF
第 2 章 方向标志操作指令串操作指令中,需要使用
CLD ;复位方向标志,DF← 0
STD ;置位方向标志,DF← 1
第 2 章 中断标志操作指令
在编写中断服务程序时,需要控制可屏蔽中断的允许和禁止
CLI ;复位中断标志,DF← 0
STI ;置位中断标志,DF← 1
第 2 章 空操作指令
NOP
不执行任何操作,但占用一个字节存储单元,空耗一个指令执行周期
NOP常用于程序调试
在需要预留指令空间时用 NOP填充
代码空间多余时也可以用 NOP填充
还可以用 NOP实现软件延时
事实上,NOP和 XCHG AX,AX的指令代码一样,都是 90H
NOP
第 2 章 段超越前缀指令
在允许段超越的存储器操作数之前,使用段超越前缀指令,将采用指定的段寄存器寻址操作数
CS,;使用代码段的数据
SS,;使用堆栈段的数据
DS,;使用数据段的数据
ES,;使用附加段的数据第 2 章 封锁前缀指令
LOCK ;封锁总线
这是一个指令前缀,可放在任何指令前
这个前缀使得在这个指令执行时间内,8086 处理器的封锁输出引脚有效,即把总线封锁,使别的控制器不能控制总线;直到该指令执行完后,总线封锁解除第 2 章 暂停指令
HLT ;进入暂停状态
暂停指令使 CPU进入暂停状态,这时
CPU不进行任何操作 。 当 CPU发生复位或来自外部的中断时,CPU脱离暂停状态
HLT指令可用于程序中等待中断 。 当程序中必须等待中断时,可用 HLT,
而不必用软件死循环 。 然后,中断使
CPU脱离暂停状态,返回执行 HLT的下一条指令交权指令
ESC 6位立即数,reg/mem;把浮点指令交给浮点处理器执行
浮点协处理器 8087指令是与 8086的整数指令组合在一起的,当 8086发现是一条浮点指令时,就利用 ESC指令将浮点指令交给 8087执行
实际编写程序时,一般采用易于理解的浮点指令助记符格式
ESC 6,[SI];实数除法指令,FDIVdword ptr [SI]
ESC 20H,AL;整数加法指令,FADDST(0),ST
第 2 章第 2 章 等待指令
WAIT ;进入等待状态
8086利用 WAIT指令和测试引脚实现与
8087同步运行
浮点指令经由 8086处理发往 8087,并与 8086本身的整数指令在同一个指令序列;而 8087执行浮点指令较慢,所以 8086必须与 8087保持同步第 2 章 第 2章 总结
本章详细而完整地介绍了 8086的 16位指令系统的每条指令
希望大家进行一下整理 ( 总结 ),
寻址方式
指令支持的操作数形式
指令对标志的影响
常见编程问题
通过复习整理,形成指令系统的整体概念,进而掌握常用指令第 2章 教学要求 ( 5)
1,掌握基本指令,JMP/ Jcc,JCXZ/ LOOP、
CALL/ RET,INT n
2,熟悉特色指令,IRET,NOP
3,了解不常使用的指令,LOOPZ/ LOOPNZ、
INTO,LOCK/ HLT/ ESC/ WAIT
4,习题 4( p73)
2.32 2.34 2.36 ⑶ ⑹ ⑺
2.39 2.44
课间休息