微机原理与接口技术讲课教师:王爱学本课程研究的内容
1,计算机硬件:构成计算机的各种元件,器件和设备实物 。
2,计算机软件:为应用计算机所编制的程序 。
微机原理课程与其它课程的关系:
数字逻辑 ―― 计算机原理 ―― 计算机汇编语言 ―― 微机原理
―― 计算机网络
―― 单片机原理本学期所学课程实际上包括了汇编语言部分 。
汇编语言:是与计算机硬件密切相关的程序设计语言,其基本语句对应硬件的一个基本命令 。
课程要求
1,3次以上 ( 包括 3次 ) 不交作业的同学不许参加期末考试,期末考试成绩计为 0分 。
2,无故不上理论课累计 3次以上 ( 包括 3次 ) 的同学不许参加期末考试,期末考试成绩计为 0分 。
3、无故不上实验课累计 3次以上(包括 3次)的同学不许参加期末考试,期末考试成绩计为 0分。
参考书
1,罗克露,徐洁:微型机原理与应用 ( 电子工业出版社 )
2,沈美明,温冬婵:汇编语言程序设计 ( 清华大学出版社 )
3,熊桂喜,IBM- PC汇编语言程序设计 ( 科学出版社 )
4,周明德:微型计算机原理及应用 ( 清华大学出版社 )
第一章 基础知识
1.1 二进制数,十进制数及十六进制数 ( 及其转换 ) ( 略 )
1.2 二进制数与十六进制数的运算
1.2.1 算术运算 ( 略 )
1.2.2 逻辑运算例:
X= 00FFH= 0000 0000 1111 1111B
Y= 5555H= 0101 0101 0101 0101B
按位,与,运算
0000 0000 1111 1111B
∧ 0101 0101 0101 0101B
―― ―― ―― ―― ―― ――
0000 0000 0101 0101B
按位,或,运算
0000 0000 1111 1111B
∨ 0101 0101 0101 0101B
―― ―― ―― ―― ―― ――
0101 0101 1111 1111B
按位“异或”运算
0000 0000 1111 1111B
0101 0101 0101 0101B
―― ―― ―― ―― ―― ――
0101 0101 1010 1010B
1.3 ASCII码和 BCD码 ( 略 )
1.4 数值与编码的转换把 ASCII码和 BCD等转换成对应的数值 。
例:
2 的 ASCII码为 32H,转换成数值为,00000010 ( 计算机中 )
在程序中,使用一定的算法进行转换 。
第二章 IBM—PC计算机组织
2.1 IBM—PC微型计算机的基本结构计算机由三大部分组成:
中央处理器 CPU( 包括运算器,控制器 ) 。
存储器 。
输入/输出设备 。
各组成部分的功能,
运算器:负责执行所有的算术和逻辑运算 。
控制器:负责指令执行时的控制工作 ( 把指令逐条从存储器中取出,经译码分析后发出取操作数,执行,
存储运算结果等控制指令 ) 。
存储器 (内存 ):是计算机的记忆部件,它通过总线与
CPU相连 。 用来存放程序执行时所需的指令和数据 。
I/ O设备:软盘驱动器,硬盘,显示器,键盘,打印机等设备 。
总线:包括数据线,地址线,控制线 。
图 2,1 PC机的一般结构中央处理器
CPU
总线控制器存储器
(内存 )
接口接口
I/O设备
I/O设备
IBM—PC系列机 CPU型号:
Intel 8086/ 8088
8088是一个准 16位的微处理器,即它的内部结构是 16
位的,而外部的数据总线是 8位的,因而它在一个总线周期内只能访问一个 8位字节而不是一个 16位的字 。
8086的内部结构和外部总线都是 16位的,工作性能比
8088好 。
80386,80486:是 32位微处理器 。
Pentium(80586):地址线 36位,外部数据线 64位 。
目前,CPU主频在 2GHz左右是常见的计算机配置 。
2.2 IBM—PC上的软件与汇编语言软件可分为两大类:系统软件和应用软件 。
2.2.1 系统软件和应用软件系统软件:由 PC机的生产厂家及其配套设备的供应商为用户提供的一组程序,这些程序是用户使用机器时为产生,准备和执行用户程序所必需的 。 ( 典型的系统软件:操作系统 )
应用软件:用户自己和一些生产商为某种应用而编写的专门软件 。
2.2.2 高级语言,汇编语言,机器语言机器指令是由二进制代码组成的,直接以指令来编程的语言便是机器语言 。 ( 编程者使用不方便 )
汇编语言:用符号以一定的简单语法来表示机器指令,
其语句与机器语言一一对应 。
高级浯言:以人们易于理解的语句和构造来编程的语言称为高级浯言,如 C,BASIC,PASCAl,FORTRAN,C+
+等 。
高级浯言 ―― 用编译程序编译 ―― 机器语言汇编语言源程序 ―― 用汇编器汇编 ―― 机器语言高级语言易学易用,基本符合数学语言和自然语言的习惯,而用汇编语言编程则要困难得多 。
为什么要学习汇编语言?
1,通过汇编语言去理解计算机运行软件的过程 。 ( 汇编语言与机器指令基本上是一一对应的 )
2,某些底层系统软件必须用汇编浯言来编写,例如主板上的 BIOS及一些设备的驱动程序 。 这是由于要直接与下层硬件打交道,高级语言很难胜任 。
3,汇编语言程序的执行效率高,运行代码占用内存少 。
有些软件的程序段需要频繁执行且要求速度快,必须使用汇编语言 。
例,Windows环境下的写屏软件,图形,图像处理中的压缩还原过程 。
2.2.3 汇编语言的开发环境 (略 )
( 以后在上机实验前进行详细的学习 。 )
2.3 Intel 8086/ 8088CPU的寄存器结构
8086CPU,16位 CPU,时钟频率,5MHz-- 10MHz
数据线,16根,可处理 8位或 16位数据地址线,20根,地址空间,220 = 1MB
8088CPU,16位 CPU,时钟频率,5MHz-- 10MHz
内部数据线,16根,可处理 8位或 16位数据外部数据线,8根,可处理 8位数据地址线,20根,地址空间,220 = 1MB
2.3.1 通用寄存器通用寄存器共 8个 (右图 )
分两组,数据寄存器 (前 4个,AX,BX,
CX,DX)用作存放数据 。
指针和变址寄存器 ( 后 4个 ),用于存放指针 。
1,数据寄存器
AX,BX,CX,DX可分别拆分成 2个 8位寄存器 。
AX:累加器 (accumulator),在算术运算时,用 AX来存放操作数和运算结果 。
BX:基址寄存器 (base address),计算存储器地址时使用 。
CX:计数寄存器 ( count),循环,串操作时用于计数 。
DX:数据寄存器 (data),双倍字长运算时,存放高 16位 。
2,指针及变址寄存器
SP:堆栈指针 (stackpointer),指示堆栈栈顶的偏移地址 。
BP:基址指针 (base pointer),也是一种基地址寄存器 (类似于 BX),所不同的是它相对于堆栈段而不是数据段 。
SI:源变址寄存器 (source index):用作地址指针,在寻址时提供地址偏移量 。 ( 主要用于串处理指令 ) 。
DI:目的变址寄存器 (destination index):
用作地址指针,在寻址时提供地址偏移量 。 ( 主要用于串处理指令 ) 。
2.3.2 段寄存器
CS:代码段寄存器 (code segment):存放代码段的段地址 。 程序执行时必须有代码 段 。
DS:数据段寄存器 (data segment):存放数据段的段地址 。
SS:堆栈段寄存器 (stack segment):存放堆栈段的段地址 。 设置堆栈段是为了给入栈操作和出栈操作保留临时数据区 。
ES:附加段寄存器 (extra segment):存放的是附加数据段的段地址 。 当一个程序同时用到 —
个以上的数据段时,附加段就是必不可少的 。
IP:指令指针寄存器 (instruction pointer)是专用的 16位寄存器,它表示的是当前要执行的指令在代码段中的偏移地址 。
程序员不能直接访问 IP,只有转移指令,子程序调用及返回指令,中断调用及返回指令才能修改 IP(有时还会修改 CS)。
2.3.4 标志寄存器标志寄存器:用于表示程序运行时 ( 数据处理时 ) 的状态 。
各标志位的作用:
进位标志 CF(carry flag):有进位或借位时为 l;
奇偶标志 PF(parity flag):结果低 8位,1”的个数为偶数时为 l。
辅助进位标志 AF(auxiliary carry flag):进行算术运算时,
如果低 4位产生了进位时为 l。 此标志用于十进制运算时的调整 。
零标志 ZF(zero flag):运算结果为 0时为 1。
符号标志 SF(sign flag):等于运算结果的最高位 ( 符号位 ) 。
溢出标志,OF(overflow flag),溢出时为 1。
OF DF IF TF SF ZF AF PF CF
以下几个标志可暂不讲述 。
跟踪标志 TF(trap flag),当 TF= 1时,在执行完一条指令后就会产生单步中断,然后由单步中断处理程序把
TF置为 0。 TF标志用于调试 。
中断标志 IF(interrupt flag),当 IF= 1时,允许响应可屏蔽中断,否则关闭中断 。
方向标志 DF(direction flag),DF用于控制串操作指令地址的增减 。 如果 DF= 1,则每次串操作后使变址寄存器 SI和 DI减 l(字节指令 )或减 2(字指令 );如果 DF= 0,
则每次串操作后使变址寄存器 SI和 DI加 l(字节指令 )或加 2(字指令 )。
2.4 PC机的内存组织
Intel 8086/ 8088:有 20根地址线,总的内存大小为 220= 1 MB。
2.4.1 内存地址与字节,字的存放
8位二进数:一个字节 (byte)。
位 7 6 5 4 3 2 1 0
内存单元的基本单位为字节,每个内存单元都分配了一个唯一的地址 。
地址范围,0000 0000 0000 0000 0000B ----
1111 1111 1111 1111 111lB
十六进制数表示,00000H— FFFFFH
16位的信息称为 1个字,任何相邻两个单元都可以组成 1个字 。
字的地址是第 1个字节的地址 。
在内存中,低字节在前,高字节在后 。
地址 存储单元 (字节 )
00000H 0
00001H
FFFFFH 1MB
……
例:
(a)将字节 12H及 34H分别放入 AH,AL寄存器;
AH AL
例:
(b)将字 1234H放入 AX寄存器;
AH AL
12H 34H
12H 34H
例:
(c)将字节 12H及 34H分别放入内存单元 1FFFFH及 20000H处;
地址 内容
……
1FFFFH 12H
20000H 34H
……
例:
(d)将字 1234H放入内存单元
1FFFFH处。
地址 内容
……
1FFFFH 34H
20000H 12H
……
例:将双字 12345678H(32 位二进制 ) 存入内存单元
1FFFFH处 。
地址 内容
……
1FFFFH 78H
20000H 56H
20001H 34H
20002H 12H
……
2.4.2 内存地址的分段
Intel 8086/ 8088有 20根地址线,其内存寻址空间为 1 MB。
为了表示某个地址,需要 20位 。
机器字长为 16位,它能表示的最大内存空间为 216= 64 KB。
Intel 8086/ 8088采用分段访问内存的办法,使得 16位寄存器可以访问 20位地址 ( 64K个段,每段最多 64KB) 。
位 19 0
物理地址位 15 0
段地址 0000
位 15 0
段内地址
2.4.3 物理地址和逻辑地址
20位物理地址采用 Intel的分段方法将其分为 16位的段地址和 16位的段内地址 (偏移值 )。
用段地址和偏移地址来表示内存单元地址的形式称为逻辑地址,写成,段地址:偏移地址,的格式 。
例:物理地址 00000H:
0000H,0000H
段地址乘以 16(左移 4位 )再加上偏移地址,即可得到物理地址 。
段地址 × 16D(或 10H)+偏移地址=物理地址例:设逻辑地址为 1234H,5678H,则物理地址为:
1234H× lOH+ 5678H= 12340H+5678H= 179B8H
如果给定一个物理地址,要算出它的逻辑地址,则有很多个结果 。
例,179B8H的逻辑地址如下:
1000H,79B8H
1001H,79A8H
1234H,5678H
179BH,0008H
1234H,5678H只是各种分段结果中的一种 。
段地址中增加 l,内存空间就增加 16D(10H)。 16字节称为
1节 (paragraph),英文简写的 para就代表 1节 。
2.4.4 实际内存分配方法例:假定一个程序的代码段大小为
4096D,数据段大小为 8180D,堆栈段大小为 252D。
按节方式 上舍入为 4096D,8192D,256D,
即 1000H,2000H,100H。
设给此程序分配的内存区从 21000H开始
(节边界对齐 ),这三个段在内存中的位置为:
段寄存器
CS 2100H
DS 2200H
SS 2400H
ES
内存
……
21000H
代码段
21FFFH
22000H
数据段
23FFFH
24000H
堆栈段
240FFH
……
内存起始地址 21000H,起始段地址为 2100H。
代码段,数据段,堆栈段大小依次为:
1000H,2000H,lOOH。
SS= DS+200H= 2400H。
代码段,数据段及堆栈段的偏移地址范围分别为:
0~ 0FFFH,0~ 1FFFH,0~ FFH。
2.5 堆栈堆栈 (stack):是内存中的一块特定区域,用于暂时缓存数据 。
2,5,1 堆栈在哪里堆栈由软件设置,是在内存中划出一块区域作为堆栈 。 堆栈的一端位置固定 ( 栈底 ),另一端是浮动的 ( 栈顶 ) 。 信息的存取在栈顶进行 。
堆栈的位置和大小由 SS及 SP寄存器确定 。
例:
设开始时 ( 栈底 ) 位置为,SS= 2400H,SP= 100H,运行一段时间后,堆栈中压入了一些数据,SP= 80H。 堆栈位置如下图所示 。
堆栈的栈底由初始 SP值决定,它等于堆栈段中最大数据单元处的地址加 1( 栈底不存数据 ) 。
堆栈的栈顶也由 SP值决定,随着不断的压栈操作,SP的值会减小,栈顶也就相应地变化 。 如果未压入内容,或压入了内容后,又全部弹出,则栈顶与栈底相同 。
段寄存器
CS
DS
SS 2400H
ES
SP 0080H
内存
……
堆栈段 24000H
24080H( 栈顶 )
24 100 H ( 栈底 )
……
无论是压入还是弹出,都是以字为单位进行 ( 不能进行字节或双字操作 ) 。
例:设 SS= 2000H,SP= 100H,试分析如下一小段程序中 PUSH
语句的执行过程 。
MOV AX,1234H ;将 1234H送入 AX
PUSH AX ;将 AX中的内容压入堆栈执行 PUSH AX指令的过程:
(1) SP ← SP- 2 ;将堆栈指针减 2
(2) (SP) ← AX ;将 AX中的一个字送入堆栈段内由 SP指向的偏移地址处段寄存器
CS
DS
SS 2000H
ES
SP 0100H
内存
……
堆栈段 2000H,0000H
20 00 H,0100H
……
出栈指令为,POP AX,工作过程和入栈操作相反 ( 略 ) 。
段寄存器
CS
DS
SS 2000H
ES
SP 0 0FE H
AX 1234H
内存
……
堆栈段 2000H,0000H
34H 20 00 H,00FEH
12H 20 00 H,00FFH
20 00 H,0100H
……
第三章 寻址方式与指令系统
3.1 指令格式指令结构,
操作码:指明计算机所要执行的操作 。
操作数地址:指出指令在执行过程中要处理的数据地址 。
操作码 操作数地址
3.2 寻址方式寻址方式:是指指令中寻找操作数的方式 。
1,立即寻址 ( 用于寄存器赋值 )
例,MOV AX,2056H
内存
……
MOV 30000H
56H 30001H
20H 30002H
……
AX
AH AL
2.寄存器寻址寄存器寻址:指令中所需的操作数在 CPU的某个寄存器中 。 存取这类操作数完全在 CPU内部进行,不需要动用总线访问内存,所以执行速度比较快 。
例:
MOV AX,BX ;源和目的操作数都是寄存器寻址方式
MOV AX,1234H
ADD BX,AX
PUSH DS ;源操作数是寄存器寻址方式
3,直接寻址直接寻址,操作数的偏移地址 (有效地址 )直接在指令中指出 。
例:
MOV AX,[1000H] ; 1000H为有效地址
( 设,DS= 2000H)
内存
……
OP 代码段
00
10
……
20000H
…… 数据段
21000H 40
30
……
AX
AH AL
4,寄存器间接寻址操作数的有效地址 EA不是位于指令中,而是位于基址寄存器
BX,BP或变址寄存器 SI,DI中 。 地址是通过一个寄存器来指明,因而称为寄存器间接寻址 。
例,MOV AX,[DI]
设 DS= 3000H,DI= 2000H
物理地址,30000H+ 2000H= 32000H
内存
……
30000H
…… 数据段
32000H B0
40
……
AX
AH AL
段跨越前缀举例:
MOV CX,ES:[BX]
MOV BX,ES:[2000H];键入字符串并显示
data segment
string db 30,0,30 dup(?);最大串长,实际串长,串
str1 db 13,10,'$'
data ends;
code segment
assume cs:code,ds:data
keyin proc far
begin,mov ax,data
mov ds,ax
mov dx,offset string ;指定数据缓冲区首地址
mov ah,0ah ;21h号中断的 0ah号功能
int 21h ;接收从键盘键入的数据到缓冲区
mov cl,string+1 ;取 实际串长度
xor ch,ch ;cx中是 实际串长度
add dx,cx ;dx指向 (串尾部- 2)的内存单元
add dx,2 ;dx指向串尾部
mov bx,dx ;必须使用 bx间接寻址
mov byte ptr[bx],'$’
lea dx,str1
mov ah,9 ;21h号中断的 09h号功能
int 21h ;显示回车换行
lea dx,string+2 ;键入串的起始地址
mov ah,9
int 21h ; 显示键入的串
mov ah,4ch ;21h号中断的 4ch号功能
int 21h ;返回 DOS操作系统
keyin endp ;过程结束
code ends ;代码段结束
end begin ;指出 可执行的第一行代码地址; 键盘键入的小写字符按大写显示
data segment
string db 2,0,2 dup(?)
data ends;
code segment
assume cs:code,ds:data
keyin proc far
begin,mov ax,data
mov ds,ax
loop1,mov dx,offset string
mov ah,0ah
int 21h
mov al,string+2
cmp al,'!'
jz done
cmp al,61h
jb loop1
cmp al,7ah
ja loop1
sub al,20h
mov string+2,al
mov string+3,'$'
lea dx,string+2
mov ah,9
int 21h
jmp loop1
done,mov ah,4ch
int 21h
keyin endp
code ends
end begin
5,寄存器相对寻址寄存器相对寻址 (变址寻址 ):操作数的有效地址 EA是一个基址寄存器或变址寄存器的内容和指令中指定的 8位和 16位位移量之和:
EA= [BX]+8位或 16位位移量
[BP]+8位或 16位位移量
[SI]+8位或 16位位移量
[DI]+8位或 16位位移量例:
MOV AX,[2040H + BP]
若,SS = 5000H BP = 3000H
则,EA = 3000H + 2040H = 5040H
物理地址 = 50000H + 5040H = 55040H
内存
……
OP 代码段
OP
40H
20H
……
50000H
…… 堆栈段
55040H 48
55
……
AX
AH AL
SS 5000H
BP 3000H
6,基址加变址寻址特点:有两个寄存器出现在指令中 。 其中基址寄存器为
BX或 BP,变址寄存器为 SI或 DI。
例:
MOV AX,[BX][SI]
MOV AX,[BX+SI] ;等同上一条指令设,DS = 3200H,BX = 0456H,SI = 1094H
则,EA = 0456H + 1094H = 14EAH
物理地址 = 32000H + 14EAH = 334EAH
7,相对的基址加变址寻址:
例:
MOV AL,[BX+ DI+ 12]
设,DS = 8000H,BX = 0100H,DI = 0010H
则 物理地址 = 80000H+ 0100H+ 0010H+ 12( 或者是 0CH)
= 8011CH
3.1.2小节 (补充 )
8086/8088 的机器语言格式 ( 1- 7个字节构成指令 )
机器指令的第一字节:
其中:
D 指出下一字节 REG段是源还是目的 。
1-目的操作数是在寄存器,否则,源操作数在寄存器 。
( 双操作数指令中,至少有一个操作数在寄存器,源为立即数除外 。 )
W 字操作位,1--字操作,否则是字节操作 。
7 6 5 4 3 2 1 0
操作码 D W
机器指令的第二字节:
MOD = 11
表示寄存器寻址
R/M 表示寄存器
MOD = 其它表示存储器寻址,R/M 表示内存地址
MOD = 11时:
若 W= 0 则,R/M 000 001 010 011 100 101 110 111
表示 AL CL DL BL AH CH DH BH
若 W= 1 则,R/M 000 001 010 011 100 101 110 111
表示 AX CX DX BX SP BP SI DI
7 6 5 4 3 2 1 0
MOD REG R/M
例,ADD CL,BH
机器语言指令,00F9H
0000000011111001
000000 0 0 11 111 001
加源操作数寄存器 BH
CL
字节操作下一字节的 REG段是源
MOD = 00时,存储器寻址,不带位移量 。
由 R/M段指出内存地址 。
000 001 010 011 100 101 110 111
[BX+SI] [BX+DI] [BP+SI] [BP+DI] [SI] [DI] 直接寻址 [BX]
其中直接寻址方式:下两个字节 ( 第 3- 4字节 ) 是 16位直接地址 。
MOD = 01时,存储器寻址,带一个位移量字节( 8位位移量)。
由 R/M段指出内存地址。
MOD = 10时,存储器寻址,带 2个位移量字节( 16位位移量)。
由 R/M段指出内存地址。
例,ADD 2145H[BX][DI],DX
机器语言指令,01914521H
00000001100100010100010100100001
000000 0 1 10 010 001 01000101 00100001
加 源 字 DX 45H 21H
2字节位移量存储器寻址 BX+ DI
立即寻址的机器指令第一字节:
S 符号扩展,8位补码扩至 16位 。
SW = 00 8位操作数
SW = 01 16位操作数
SW = 11 8位操作数扩展至 16位
( SW = 10 无效 )
7 6 5 4 3 2 1 0
操作码 S W
例,ADD 2345H[BX][DI],-105
机器语言,8381452397H
1000001110000001010001010010001110010111
100000 1 1 10 000 001 01000101 00100011
字 10010111
- 105补码符号扩展带立即数加法
2字节位移量存储器寻址
BX+ DI
设:指令执行前:
BX = 0892H DI = 59A3H
DS = 2000H ( 2857AH) = 0029H
目的操作数地址:
20000H+ 2345H+ 0892H+ 59A3H = 2857AH
指令执行后:
( 2857AH) = 0029H+ 0FF97H = 0FFC0H
0FF97H是 97H的带符号扩展:
1111111110010111
注意事项:
使用 BP的间接寻址,SS为默认段寄存器 。
其它,DS为默认段寄存器 。
有段跨越前缀时,在指令前加一个字节:
SEG,00 ES 01 CS 10 SS 11 DS
三种情况不允许段跨越:
程序:必为 CS 堆栈:必为 SS 串操作的目的串:必为 ES
7 6 5 4 3 2 1 0
001 SEG 110
3.3 指令系统
Inlel 8086/ 8088的指令系统可分成以下六组:
数据传送指令 。
算术指令 。
逻辑指令 。
串处理指令 。
控制转移指令 。
处理机控制指令 。
3.3.1 数据传送指令数据传送指令负责把运算过程中所需的数据,地址或立即数传送到寄存器或存储单元中 。
1.数据通路与类型匹配数据传送指令的作用,就是在内存、通用寄存器、段寄存器、立即数之间,传来传去,。在传送指令的源操作数和目的操作数之间,传什么,如何传,既要根据程序的需要来设置,还要根据语法规则及数据通路来决定。
通用寄存器
AX,BX,CX,DX
SP,BP,SI,DI
段寄存器
CS,DS,SS,ES
内存 立即数
2,MOV和 XCHG指令
MOV指令的语法为:
MOV DST,SRC
根据数据通路图可知如下指令是合法的 (其中 ac为立即数,
reg为通用寄存器,segreg为段寄存器,mem为内存 ):
MOV reg,ac MOV mem,ac
MOV reg,reg MOV mem,reg
MOV reg,segreg MOV mem,segreg
MOV reg,mem MOV segreg,reg
MOV segreg,mem
当使用段寄存器作目的操作数时,不允许使用 CS作目的操作数 。
MOV或其他大多数指令必须遵守以下规则:
1)源和目的必须类型匹配 (8位对 8位,16位对 16位 )。
2)目的操作数不能为立即数 。
3)源和目的操作数不能同时为内存操作数 (串指令除外 )。
4)源和目的操作数不能同时为段寄存器 。
下面的指令不正确:
(1) MOV AX,BL
(2) MOV ES,DS
(3) MOV [DI],[SI]
可以将它们改为:
(1) MOV AL,BL
MOV AH,0
(2) MOV AX,DS
MOV ES,AX
(3) MOV AL,[SI] MOV [DI],AL
例:
MOV DL,CL
MOV AX,BX
MOV AX,[2010H]
MOV CL,[BX+5]
MOV [SI],CX
MOV AL,32H
MOV CX,2801H
MOV DS,AX
MOV SS,DX
XCHG OPRl,OPR2 ;将两个操作数的内容互换 (不允许任何一个操作数是立即数 )
例,XCHG BX,[BP+SI] ;将 BX中的内容与堆栈段内容互换
XCHG及 MOV指令执行后都不影响标志寄存器 。
例:将有效地址为 1000H开始的内存中 100个连续存储单元清零 。
MOV DI,1000H
MOV CX,64H ;64H=100
MOV AL,0
BBB,MOV [DI],AL
INC DI
DEC CX
JNZ BBB
其中,BBB为符号地址
3,PUSH,POP,PUSHF,POPF指令
PUSH,POP 入栈出栈指令
PUSHF,POPF 标志寄存器入栈出栈指令例:
在程序中的某一部分里要临时借用一下某个寄存器,但借用前的内容以后还有用,就可以先用 PUSH指令将其保存起来,
然后在必要时再用 POP指令恢复成原来的内容 。
PUSH CX
PUSH AX
…… ;其间的程序要借用 CX,AX
POP AX ;恢复 AX内容
POP CX ;恢复 CX内容利用堆栈还可以传递内容 。 例:
PUSH DS
POP ES ; ES的内容 =DS的内容
4,地址传送指令 LEA,LDS,LES
LEA reg,src ;将源操作数 src的偏移地址送入 reg
例,LEA BX,[BX+0400H]
执行前,BX=2000H
执行后,BX=2000H+0400H=2400H
LDS reg,src ;将 src中的双字内容依次送入 reg及 DS
例,LDS SI,[2030H]
执行前,DS=5000H (52030H) = 0240H
(52032H) = 3000H
执行后,SI=0240H
DS=3000H
LES reg,src ;将 src中的双字内容依次送入 reg及 ES
3.3.2 算术运算指令
1,加法和减法指令主要的六条加法和减法指令如下:
ADD dst,src
ADC dst,src ; src + dst + CF,带进位加
INC opr ;操作数自加 1
SUB dst,src
SBB dst,src ;带借位减
DEC opr
其中,dst,src及 opr既可以是字节操作数,也可以是字操作数,但类型必须匹配 。
除了 INC及 DEC指令不影响 CF(进位标志 )外,所有指令都会影响标志寄存器,其中最重要的是 CF,ZF,SF,OF,分别表示进位,结果为零,符号和溢出 。
例,ADD AL,70H
ADD BX,3000H
ADD SI,CX
ADD DX,[BX+DI]
ADD [BX+SI],AX
例,32位加法运算:
设,DX=0007H AX=A379H 0007A379H
BX=0005H CX=7E4FH 00057E4FH
指令为:
ADD AX,CX
ADC DX,BX
A379
+ 7E4F
--------
1 21C8
0007
0005
+ 1
--------
000D 结果,DX=000DH AX=21C8H
例:
INC BL
INC CX
INC BYTE PTR[BX]
下面的指令有错误:
(1) ADD [SI],13H
(2) SUB AX,BL
指令应改为:
(1) ADD WORD PTR[SI],13H
(2) MOV BH,0
SUB AX,BX
例:求 Z= X- Y。 X,Y,Z都是一个 32位数 。
X DD? ;在数据段中定义一个双字
Y DD?
Z DD?
……
MOV DX,WORD PTR X+2 ;用 DX,AX作为被减数,;双字的高位字在后,地址加
2;双字中的字,必须用 PTR 运算符
MOV AX,WORD PTR X ;双字的低位字在前
SUB AX,WORD PTR Y ;先进行低 16位减法
SBB DX,WORD PTR Y+ 2 ;高 16位减法用 SBB,考虑借位
MOV WORD PTR Z,AX ;差的低 16位
MOV WORD PTR Z+2,DX ;差的高 16位
2,比较指令 ( 两数相减,仅影响标志位 ),
例:
CMP AL,64H
CMP BX,21F0H
CMP CL,DH
CMP AX,[BX+SI+04]
相等时,ZF= 1( 否则为 0)
例:找出 100个无符号 8位数的最大值 (有效地址 3000H开始的 100个无符号数 )。
……
MOV BX,3000H ;起始地址
MOV CX,63H ;99次比较
MOV AL,[BX]
LP1,INC BX
CMP AL,[BX]
JNC LP2 ;无借位转移,大于等于转移
MOV AL,[BX]
LP2,DEC CX
JNZ LP1
MOV MAX,AL ;最大值送 MAX单元
……
例:找出 50个有符号 16位数的最小值 (有效地址 3000H开始的 50个有符号数 )。
……
MOV BX,3000H ;起始地址
MOV CX,31H ;49次比较
MOV AX,[BX]
BBB,INC BX
INC BX
CMP AX,[BX]
JNG CCC ;有符号数小于等于转移
MOV AX,[BX]
CCC,DEC CX
JNZ BBB
MOV MIN,AX ;最小值送 MIN单元
……
3,乘法指令
8位乘法,积在 AX中 。
16位乘法,积在 DX(高),AX(低)中。
1、无符号数乘法
MUL CL ; AL乘 CL送 AX
MUL BX
MUL BYTE PTR[SI] ;8位乘
MUL WORD PTR[DI] ;16位乘
2、有符号数乘法
IMUL BL
IMUL CX
究竟是使用 MUL还是 IMUL取决于你怎样看待操作数 (包括乘数和被乘数 )。
例:设 AL= 11111111B,BL= 11111111B。
如果使用 MUL BL 指令,则 11111111B× 11111111B =
255D× 255D= 65205D。
如果使用 IMUL BL 指令,则是 (-1)× (-1)= 1。
乘法指令会影响标志位 。 但除了 CF和 OF以外的标志位无定义 。
注意:乘数不能为立即数 。
X(字节 )乘以 10的指令如下:
MOV AL,10
MUL X ;结果在 AX中绝不能写成以下形式:
MOV AL,X
MUL 10
注意,不能以 16位操作数乘 8位操作数,必须将 8位操作数扩展成 16位操作数 。 对无符号 8位操作数,扩展成 16位时,只需将高 8位清零 。 对有符号的 8位操作数,扩展成 16位时,要使用 CBW指令 。
CBW指令无参数,它的作用是将 AL的符号扩展至 AH。 如果
AL的最高位为 0,则 AH= 00;如果 AL的最高位为 1,则 AH=
0FFH。
3.3.3 逻辑指令逻辑指令包括逻辑运算指令及移位指令两大类 。
1,逻辑运算指令 (指令都是按位进行逻辑运算的 。 )
AND dst,src ;逻辑,与,
OR dst,src ;逻辑,或,
XOR dst,src ;逻辑,异或,
NOT dst ;逻辑,非,
例:
AND AL,0FH,将高 4位清零; AL= 10100101――> AL=00000101=05H
AND AL,0FOH ;将低 4位清零 ;; AL= 10100101――> AL=10100000=0A0H
AND AL,0FEH,将最低位清零
OR AL,80H,将最高位置 1
XOR AL,AL ; AL清零,比 MOV AL,0效率高
OR AL,30H ; OR之前 AL= 0~ 9,则将 AL中的值变 ASCII码; AL= 00000101――> AL=00110101=35H
AND AL,0FH ; AND之前 AL= 30H~ 39H,则将 AL中的值变;为 0~ 9; AL= 00110101――> AL=00000101=05H
2,测试指令 TEST
完成操作类似于 AND,但它不将运算结果送目的操作数,只是影响标志位 。
例:统计负数的个数 (有效地址 4000H开始的 20H个有符号数 )。
XOR DI,DI
MOV BX,4000H
MOV CX,20H
AGAIN,MOV AL,[BX]
INC BX
TEST AL,80H ;若 AL最高位为 1( 负数 ) 时,ZF= 0
JZ,GOON ;正数时跳转
INC DI
GOON,DEC CX
JNZ AGAIN
MOV MINUS,DI ……
3,移位指令移位指令共有八条,它们的指令格式分别是:
逻辑左移 SHL dst,count
算术左移 SAL dst,count
逻辑右移 SHR dst,count
算术右移 SAR dst,count
循环左移 ROL dst,count
循环右移 ROR dst,count
带进位循环左移 RCL dst,count
带进位循环右移 RCR dst,count
dst是除立即数之外的任何寻址方式 。 字或字节都可以 。
SHL,SAL移位方法相同:
← --------
最高位 最低位
← 0← CF
-------- →CF
符号位SAR移位方法:
SHR移位方法:
例,SAL AH,1
MOV CL,2
SHL SI,CL ;位移数多于 1时,必须用 CL
------- →CF 0 →
------- →CF ← →ROR
← -------CF ← ←ROL
← --------CF ← RCL
-------- →CF → RCR
例,
X= X * 10,使用移位及加法来实现 ( 速度快 ),
SHL BX,1 ;X*2
MOV AX,BX ;保存 X*2
SHL BX,1
SHL BX,1 ;X*8
ADD BX,AX ;X=X*8+X*2
需 11个时钟周期 。
使用乘法指令,则需要 70个时钟周期 。
例,32位数乘 4。 用左移 2位完成乘 4。 用两个寄存器
DX及 AX来表示 32位数 。
X DD? ; X为一个 32位数
……
MOV AX,WORD PTR X ;取低 16位
MOV DX,WORD PTR X+ 2 ;取高 16位
SHL AX,1 ;低 16位左移 l位,;移出的位在 CF中
RCL DX,1,高 16位带进位循环左移,;低 16位的进位位移入高 16位的最低位
SHL AX,1
RCL DX,l
P60页第 2题答案:
1) MOV [CX],AL
不能用 CX间接寻址。
2) MOV BH,320
溢出。
3) MOV DS,2000H
没有数据通路。
4) ADD SI,FDDH
补 0为 0FDDH。
5) SHL AX,2
移位数大于 1时用 CL寄存器。
6) CMP BYTE PTR [SI],X
不能都是内存单元。
7) LEA BX,[SI]
正确。
8) LDS BX,[DX]
不能用 DX间接寻址。
9) JMP BYTE PTR AX
PTR不能在寄存器前。
10) JMP AX
正确。
11) JMP [AX]
不能用 AX间接寻址。
12) RET 5
RET后必须是偶数。
13) MOV [BX+SI+10],100
必须指明字或字节。
14) DIV AL
AX为被除数,AL为除数,
当 (AH)>(AL)时,结果可能溢出。
P60页第 3题答案:
1) 5634H
2) 7856H
3) 78H
4) 7856H;P60页 5(1) 求 Z= X+Y。 X,Z是 32位数,Y是 8位数。
data segment
X DD 1111FFFFH
Y DB 2
Z DD?
data ends;
code segment
assume cs:code,ds:data
XYAdd proc far
begin,mov ax,data
mov ds,ax;
MOV DX,WORD PTR X+2;用 DX,AX作为被加数.;双字的高位字在后,地址加 2
MOV AX,WORD PTR X ;双字的低位字在前
MOV BL,Y ;字的低 8位
XOR BH,BH ; BX中为 16位数,等于 Y
ADD AX,BX ;先进行低 16位加法
ADC DX,0 ;高 16位加法,考虑进位
MOV WORD PTR Z,AX ;和的低 16位
MOV WORD PTR Z+2,DX ;和的高 16位;
mov ah,4ch
int 21h
XYAdd endp
code ends
end begin
例:将 BCD码转换为 ASCII码 。
MOV SI,1000H
MOV DI,3000H
MOV CX,0004
GGG,MOV AL,[SI]
MOV BL,AL
AND AL,0FH
OR AL,30H
MOV [DI],AL
INC DI
BCD 码 内存
……
1000H 21H
43H
65H
87 H
……
ASC 码内存
……
3000H 3 1H
32 H
33 H
34H
35H
36H
37H
38 H
……
MOV AL,BL
PUSH CX
MOV CL,4
SHR AL,CL ;逻辑右移;前面补 0
OR AL,30H
MOV [DI],AL
INC DI
INC SI
POP CX
DEC CX
JNZ GGG
BCD 码 内存
……
1000H 21H
43H
65H
87 H
……
ASC 码内存
……
3000H 3 1H
32 H
33 H
34H
35H
36H
37H
38 H
……
编写完整程序的提示:
data segment
BCD1 DB 21H,43H,65H,87H
ASC1 DB 8 dup(?)
data ends
…...
…...
LEA SI,BCD1
LEA DI,ASC1
补充内容:
3.2.2 与转移地址有关的寻址方式
1,段内转移,段间转移段内转移,
转移到同一个代码段内的某个偏移地址处 。
段间转移:
转移到另一个代码段中的某个偏移地址处。
2,段内直接寻址段内直接寻址:指令的有效地址是当前 IP寄存器的内容和指令中指定的 8位或 16位位移量之和 。 指令的机器码中带有相对于当前 IP的位移量,是相对寻址 。
8 位位移量:加 SHORT 操作符 ( 叫做:短跳转 )
16位位移量:加 NEAR PTR 操作符 ( 可以省略 ) 。
例:
JMP SHORT L1 ; L1与当前 IP的位移量是一个 8位值
JMP L1 ( 或者 JMP NEAR PTR L1 ); L1与当前 IP的位移量是一个 16位值条件转移指令只能是 8位位移量,省略了 SHORT 操作符 。
3,段内间接寻址有效地址是一个通用寄存器或数据段中一个存储单元的内容 ( 寻址内存可使用任何一种寻址方式 ) 。
例:
MOV AX,OFFSET p1;获取 p1过程在代码段内的偏移值
CALL AX
例:
MOV AX,[BX] ;数据段中,寄存器间接寻址
JMP BX ;代码段中,段内间接寻址
MOV AX,OFFSET pl ;获取过程 p1的偏移地址送入 AX
MOV ADD1,AX ;将 AX内容送入数据段内的 ADD1处
CALL ADDl ;转移至 ADD1中存放的偏移地址处
MOV BX,OFFSET ADD1 ;获取 ADD1的偏移地址送入 BX
CALL [BX] ;转移地址的偏移地址位于数据段中,;要通过 BX间接寻址获取
4,段间直接寻址段间直接寻址在指令中给出了要转移的地址的代码段和段内偏移量 。
例:
CALL FAR PTR p2
要转移至的标号或过程名必须具备 FAR属性 。
5,段间间接寻址转移地址必须放入内存单元中,且是一个双字 。
例,JMP DWORD PTR[BX+ INTERS]
内存单元中的转移地址是一个双字,高位字在后,低位字在前 。 转移后,低位字变成了 IP,
高位字变成了 CS。
间接的偏移量
3.3.4 控制转移指令控制转移指令用来改变程序的执行顺序,
共有如下几类:
· 无条件转移指令 (JMP);
· 条件转移指令
· 循环指令
· 子程序调用与返回指令 。
· 中断与中断返回指令 。
1,无条件转移指令例:
JMP SHORT PTR L1 ; 转移至段内 L1标号处,;标号与当前指令距离在- 128~+ 127之间
JMP L1 ; 转移至段内 L1标号处
JMP FAR PTR L1 ; 转移至其它段内 L1标号处;此标号必须是 FAR属性
JMP BX ; 转移至段内某处,偏移值由 BX指出
BX=1300H
( IP) = 1300H
JMP [BX+DI]
若 BX= 1300H DI= 1200H DS= 3000H
( 32500H) = 2350H
执行后,( IP) = 2350H
JMP DWORD PTR [BX]
设:执行前,DS= 4000H BX= 1212H
( 41212H) = 1000H
( 41214H) = 4A00H
执行后,CS= 4A00H IP= 1000H
2,条件转移指令
JZ,JNZ,JC,JNC …… 参见书中 54页~ 55页 。
条件转移指令的标号处与当前 IP的距离必须在 -
128~ +127字节之间,即必须是 8位位移量 。
转移指令不会改变任何标志寄存器,所以可以连用两条条件转移指令,如:
CMP OPRl,OPR2
JZ L1 ;相等时,ZF=1,转移至 L1处
JNZ L2,不相等时,ZF=0,转移至 L2处例:求 Z= |X—Y|。 X,Y,Z都是无符号数 。
MOV AX,X
CMP AX,Y ;比较 X,Y
JAE L1 ;大于等于转移
XCHG AX,Y ;如果 AX<Y,则交换 AX,Y
Ll,SUB AX,Y
MOV Z,AX
3,循环指令 (不影响标志位 )
……
AGAIN,……
……
LOOP AGAIN; = DEC CX; JNZ AGAIN,AGAIN是一个标号
LOOPZ AGAIN ; CX≠0 且 ZF= 1 时循环
LOOPNZ AGAIN ; CX≠0 且 ZF= 0 时循环
4,过程调用与返回指令过程,对于在程序中重复执行或功能相对独立或完整的程序块,出于易读,结构化或其他原因,常把它们放入过程中 。
过程的定义形式:
过程名,PROC [near|far]
过程体
RET
过程名,ENDP
用 CALL指令调用过程:
CALL指令格式:
CALL dst
CALl指令与 JMP指令不同之处在于转移至 dst处前,先将 CALL下一条指令的偏移地址入栈 (段内转移 ),或将 CALL下一条指令的偏移地址和段地址入栈 。
在 CALL指令之后的下一条指令地址称为 返回地址 。
CALL指令的执行过程以段内间接调用为例:
CALL dst
SP= SP- 2; SS,[SP] 保存返回地址的偏移值
IP= dst中的有效地址例:
CALL P1 ;段内直接调用过程 P1,; P1的属性为 NEAR
CALL P2 ;段间直接调用过程 P2,; P2的属性为 FAR
CALL FAR PTR P2 ;同上
CALL BX ;段内间接寻址,;过程的地址在 BX中
CALL DWORD PTR add1 ;段间间接调用,;过程地址 CS,IP位于数据段 add1处
CALL DWORD PTR[BX] ;段间间接调用,;过程地址 CS,IP位于数据段中,;通过 BX间接寻址得到 。
RET指令的执行过程:
(1)段内返回,RET
IP←[SP] ; SP= SP+2
(2)段内带立即数返回,RET exp
IP←[SP] ; SP= SP+2
SP= SP+ exp
(3)段间返回,RET
IP←[SP] ; SP= SP+2
CS←[SP] ; SP= SP+2
(4)段间带立即数返回,RET exp
IP←[SP] ; SP= SP+2
CS←[SP] ; SP= SP+2
SP= SP+exp
说明:
段内返回或者段间返回由过程定义时的属性
(NEAR|FAR)确定的 。
段内返回的 RET经汇编器汇编后指令仍然是 RET。
段间返回的 RET经汇编器汇编后指令变成 RETF。
在 RET指令后的立即数必须为偶数 。 有些过程在被调用前,先压进了 —些参数,因而需要在返回时修改 SP,保持堆栈的平衡;
5,处理器控制命令 ( 略 )
data segment
string db 2,0,2 dup(?)
data ends;
code segment
assume cs:code,ds:data
keyin proc far
begin,mov ax,data
mov ds,ax
loop1,mov dx,offset string
mov ah,0ah
int 21h
mov al,string+2
cmp al,'!'
jz done
cmp al,61h
jb loop1
cmp al,7ah
ja loop1
sub al,20h
mov string+2,al
mov string+3,'$'
lea dx,string+2
mov ah,9
int 21h
jmp loop1
done,mov ah,4ch
int 21h
keyin endp
code ends
end begin