汇编和接口
寄存器:
以8086为例:
寄存器都是16位
通用寄存器 AX, BX, CX, DX
每个寄存器又可以分为高8位和低8位:如AX -> AH, AL 每个寄存器都可以独立使用
处理数据的尺寸
字节 byte 8位 字 word 16位
简单的汇编指令:
mov ax bx ax <- bx
add ax bx ax <- ax + bx
jmp 3:0b16 CS <- 3h IP <- 0b16h
jmp ax ip <- ax
16位cpu:
1.运算器一次最多处理16位数据
2.寄存器最大宽度位16
3.reg和alu之间的数据通路为16位
地址:(内存中没有段的划分)
20位物理地址 16位段地址 16位偏移地址 -> 一个段的最大长度为 2 << 16 = 64kb
20位地址只在内存中使用
物理地址 = 段地址 << 4 + 偏移地址
段寄存器:
CS DS SS ES (段:segment)
CS和IP:
CS 代码段寄存器 IP 指令指针寄存器
读取一个指令后IP自动增加一个指令的长度
启动,复位后 CS = FFFFH IP= 0000H
代码段:
最大64kb, 起始地址16倍数
模块化程序设计的相关问题
例子:简单的模块实例,设计一个子程序,根据提供的N,计算N的三次方
1 | assmume cs:code |
这是一个很简单的子程序,没有任何的寄存器冲突
寄存器冲突存在下的模块化设计:
1 | assume cs:code |
汇编代码の使用教程
ret和retf
ret 相当于,pop ip
适用于近迁移
retf 相当于pop ippop cs
适用于远迁移
call
CPU执行call操作的时候进行两步操作:
1.将当前的CS和IP压栈,或者只压栈当前的IP
2.转移
第一种情况:
call标号
相当于:
push IP
jmp near ptr 标号第二种情况:
call far ptr 标号
相当于:
push CSpush IPjmp far ptr 标号`第三种情况:
call 16位reg
相当于:
push IP
jmp 16位reg第四种情况:
call word ptr 内存单元地址相当于:
push IP
jmp word ptr 内存单元地址
如果是dword的话
call dword ptr 内存单元地址
相当于:
push CS
push IP
jmp dword ptr 内存单元地址
mul
格式如下:mul regmul 内存单元
分两种情况:
如果是两个8位相乘,那么结果全部放在AX中。
如果是两个16位相乘,那么结果的高16位放在DX中,低16位放在AX中。
adc
adc带进位加法指令
用法:adc ax, bx
相当于计算:(ax) = (ax) + (bx) + CF
sbb
sbb带借位的减法
用法:sbb ax, bx
相当于计算:(ax) = (ax) - (bx) - CF
cmp
cmp是比较指令, 本质上是不保存结果的减法指令
用法:cmp ax, bx
先进行计算ax - bx,计算后
![[Pasted image 20260426232144.png]]
对应的跳转指令如下:
![[Pasted image 20260426232305.png]]
pushf和popf
pushf:标志寄存器入栈popf:标志寄存器出栈
标志寄存器Related
ZF寄存器:判断相关指令结果是否为0,是0则ZF= 1PF寄存器:奇偶标准位,记录相关指令执行后结果的所以bit中1的个数是否为偶数,如果是偶数则PF= 1,16位寄存器进行操作时,只看低8位。SF寄存器,记录相关指令执行后结果是否位负,如果为负则SF= 1CF寄存器,在进行无符号数运算的时候,记录运算结果最高有效位向更高位的进位值OF寄存器,在进行有符号数的运算的时候,如果结果超过机器表示范围,称为溢出DF寄存器和串传送指令:
df是方向标志位,在传处理指令中控制si, di的增减movsb相当于执行下面几步操作
es:[di] = ds:[si]if df = 0:`(si) = (si) + 1` `(di) = (di) + 1`if df = 1:`(si) = (si) - 1` `(di) = (di) - 1`使用格式为:
rep movsb
相当于:s:movsbloop s
所以使用这个指令的时候要设置cx, si, di, es, dsmovsw具体操作与
movsb相同,si, di的步长改为2df的设置指令:cld:df <- 0sld:df <- 1
内中断
当
cpu发生以下情况时,将产生中断信息
- 除法错误,如
div的指令溢出 –中断码0 - 单步执行 –中断码1
- 执行
into指令 –中断码4 - 执行
int指令 –中断码为指令参数
中断向量表:
储存在内存的
0000:0000到0000:03FF这1024个单元中
中断过程(8086CPU):
从中断信息中获取中断类型码
标志寄存器入栈(中断过程要改变标志寄存器的值)
设置标志寄存器第八位的
TF和第九位IF的值为0CS入栈IP入栈从内存地址为
中断类型码 * 4 和中断类型码* 4 + 2两个字单元中读取中断处理程序的入口地址,设置CS和IP
相当于:1. 获取终端类型码N2. pushf3. TF = 0, IF = 04. push CS5. push IP6 (IP) = (N * 4), (CS) = (N * 4 + 2)中端处理程序和
iret指令iret指令相当于:`pop IP` `pop CS` `popf`
编程处理0号中断
现在我们考虑,重新写一个0号中断处理程序,功能是在拼命中间显示”overflow!”,然后返回系统。
为了实现这个功能我们来进行分析:
当除法发生溢出的时候,产生0号中断信息,从而引发中断过程。
此时CPU进行以下工作:
(1). 获取中断类型码0;
(2). 标志寄存器入栈,TF和IF设置为0
(3). CS, IP入栈
(4). (IP) = (0 * 4), (CS) = (0 * 4 + 2)可见中断0发生的时候,CPU将转去执行中断处理程序,只要按照以下步骤编写中断处理程序,当中断0发生的时候,即可显示“overflow!”
- 相关处理;
- 向显示缓冲区宋字符串”overflow!”;
- 返回DOS
我们将这段程序成为do0
现在问题是:do0应该放在内存中。因为除法溢出随时有可能发生,CPU随时可能将CS:IP指向do0的入口,执行程序。
内存0000:0000-0000:03ff,大小为1kb的空间是存放中断程序入口地址的中断向量表。8086支持256个中断,但是实际上系统要处理的中断远没有256个。一般情况下,从0000:0200-0000:02ff的256个字节对于空间的中断向量表是空的,我们可以把do0放到0000:0200后
程序的整体框架如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18assume cs:code
code segment
start:
do0安装程序
设置中断向量表
mov ax, 4c00h
int 21h
do0:
显示字符串"overflow!"
mov ax, 4c00h
int 21h
code ends
end start
do0的安装
可以用movsb指令,将do0的代码送入0:200处。
1 | assume cs:code |
do0
按照我们一贯的思路:
1 | assume cs:code |
看似很合理,实际上大错特错。”overflow!”在程序的data段中,当程序执行完后返回,它所占用的空间会被系统是否,其中存放的字符串很肯可能被其他的信息覆盖。
正确的程序如下:
1 | asuume cs:code |
int指令
int指令
int指令的格式为:int n,n为中断类型码,他的功能是引发中断过程。
CPU执行int n指令,相当于引发一个n号中断的过程,执行过程如下:
- 取中断类型码n;
- 标志寄存器入栈,IF = 0,TF = 0;
- CS,IP入栈
- (IP) = (n * 4), (CS) = (n * 4 + 2)
编写供应用程序调用的中断实例
问题1:编写、安装中断7ch的中断例程
功能:求一word数据的平方
参数:(ax) = 要计算的数据
返回值:dx,ax中存放高16位和低16位
应用实例:求2 * 3456 ^ 2
1 | assume cs:code |
安装程序如下
1 | assume cs:code |
注意:在中断例程sqr的最后,要实验iret指令。用汇编语言描述,iret的指令功能如下:pop IPpop CSpopf
问题2:
将一个和全是字母,以0结尾的字符串,转化为大写
参数:ds:si 指向字符串的首地址
1 | assume cs:code |
安装程序如下:
1 | assume cs:code |
int、iret和栈的深入理解
问题:用7ch中断实例完成loop指令的功能
loop s的执行需要两个信息,循环次数和到s的位移,所以,7ch中断实例要求完成loop的功能,也需要这两个信息作为参数。我们用cx存放参数,用bx存放位移。
应用举例,在屏幕中间显示80个” ! “
1 | assume cs:code |
中断实例如下:
1 | lp: |
DOS中断例程应用
int 21h中断例程是DOS提供的中断例程,其中包包含了DOS提供过程序员在编程时调用的子程序。
我们前面使用的int 21h是中断例程的4ch号功能,即程序返回功能
1 | mov ah, 4ch ;return |
(ah) = 4ch 表示调用中断例程的4ch号子程序,功能为程序返回,可以提供返回值作为参数
接下来看一看int 21h中断例程在光标位置显示字符串的功能:
1 | ds:dx 指向字符串 ;要显示的字符串需要用$作为结束符 |
编程,在5行12列显示字符串”Welcome to masm”
1 | assume cs:code |
端口
CPU可以直接读三个地方的数据:
CPU内部的寄存器
内存单元
端口
端口的读写
CPU通过端口地址来定位端口。端口所在的芯片与CPU通过总线相连,端口地址和内存地址一样,通过地址总线来传送。PC系统中,CPU最多可以定位64KB个不同的端口,则端口的地址范围为0-65535
端口的读写指令只有两条
in 和 out
访问端口:
in al, 60h 从60h端口读入一个字节
CPU通过地址线将地址信息60h发出;
CPU通过控制线发出端口读命令,选中端口所在芯片并且告诉他要读
端口所在的芯片将60h端口的数据通过数据线送入CPU
in 和 out 指令只能al 或者 ax寄存器存放从端口得到的数据或者要发给端口的数据
对0-255以内的端口进行读写的时候:
1 | in al, 20h |
对256-65535的端口进行读写时,端口号放在dx中
1 | mov dx, 3f8h |
CMOS RAM芯片
PC机中,有一个CMOS RAM芯片,特征如下:
包含一个实时钟和一个有128个储存单元的RAM存储器
芯片靠电池供电,关机信息不丢失
128个字节中,实时种占用0-0dh单元保存时间信息,其余大部分单元用于保存系统配置信息,供系统启动时BIOS程序读取
芯片内部有两个端口,70h和71h来读写CMOS RAM
70h为地址端口,存放要访问CMOS RAM单元的地址数据;71h为数据端口,存放从CMOS RAM中要读或者要写的数据。
可见,CPU对CMOS读写分两步,比如读取CMOS RAM的2号单元:
(1) 将2送入端口70h
(2)从端口71h读出2号单元的数据
shl 和 shr 指令
shl 和 shr 是逻辑移位
shl是逻辑左移,功能为:
将一个寄存器或者内存单元的数据向左移位
将最后移出的一位写入CF
最低位用0补充
如果移动位数大于1,必须把移动位数放在cl里
shr是逻辑右移,功能为
将一个寄存器或者内存单元的数据向右移位
将最后移出的一位写入CF
最高位用0补充
如果移动位数大于1,必须把移动位数放在cl里
CMOS RAM中存储时间的信息
CMOS RAM中存放着年,月,日,时,分,秒。这六个信息的长度都是一个字节,存放单元为:
秒:0 分:2 时:4 日:7 月:8 年:9
这些数据以bcd码的方式存放,一个字节可以表示两个BCD码,则CMOS RAM存储时间信息的单元里,存储了用两个BCD码表示的两位十进制数,高4位BCD码表示十位,低4位BCD码表示各位。例如:0001 0100b表示 14
编程:在屏幕中间显示当前月份的bcd码
从CMOS RAM的8号单元读取当前月份的BCD码:
1
2
3
4mov al, 8
out 70h, al ;将内存单元号写入70h
1 |
1 |
1 |
1 |
1 |
1 |
in al, 71h ;从71h端口读出指定单元的数据
1 |
|
外中断
接口芯片和端口
在pc系统的接口卡和主板上,装有各种有各种接口芯片。这些外设接口芯片内部有若干寄存器,CPU把这些寄存器当作端口来访问。
外中断信息
现在我们知道,外设的输入被存放在端口中,可是外设的输入随时有可能到达,CPU如何及时地知道,并且进行处理呢?
CPU提供中断机制来满足这些要求。与内中断不同,还有一种中断信息,来自于CPU外部,当CPU外部有需要处理的事情发生的时候,相关的芯片将向CPU发出相应的中断信息。CPU在执行了当前的指令后,可以检测到发送过来的中断信息,引发中断过程。
在CPU系统中,外中断源一共有以下两类
一. 可屏蔽中断
可屏蔽中断是CPU可以不响应的外中断。CPU是否响应,要看标志寄存器IF位的设置。如果IF = 1,CPU在执行完当前指令后会响应中断;如果IF = 0,则不响应可屏蔽中断。
回忆一下内中断的中断过程:
(1) 取中断状态码 n
(2) 标志寄存器入栈
(3) CS,IP入栈
(4) (IP) = (n * 4), (CS) = (n * 4 + 2)
可屏蔽中断引发的终端过程,除了第一步的实现有所不同外,基本上与内中断的过程相同。
当然,如果中断处理程序中需要处理可屏蔽中断时,则在执行完当前指令后,立即响应,引发中断过程,可以用指令将IF设置为1。8086CPU提供的设置IF指令如下:
sti,设置IF = 1;
cli,设置IF = 0。
二. 不可屏蔽中断
不可屏蔽中断是CPU必须响应的外中断。当CPU检测到不可屏蔽中断信息时,则在执行完当前指令后,离开响应,引发中断过程。
对于8086CPU,不可屏蔽中断的中断类型码固定为2,所以中断过程中,不需要取中断类型码,立即响应,引发中断过程:
(1) 标志寄存器入栈,IF = 0, TF = 0;
(2) CS, IP入栈;
(3) (IP) = (8), (CS) = (0ah)
PC机键盘的处理过程
1. 键盘输入
键盘上每个键相当于一个开关,键盘中有一个芯片对键盘上的每个键的开关状态进行扫描。
按下一个键后,开关接通,芯片产生一个扫描码,扫描码说明了按下的键在键盘上的位置,扫描码被送入60h端口。
松开按下的键后,也产生一个扫描码,说明了松开的键在键盘上的位置,松开时产生的扫描码也被送入60h端口。
一般按下一个键产生的扫描码叫做通码,松开一个键产生的扫描码成为断码。扫描码长度为一个字节,通码的第7位为0,断码的第七位为1,即:
断码 = 通码 + 80h
比如,g键的通码为22h,端码为a2h

2. 引发9号中断
键盘输入到达60h端口时,相关的芯片就会向CPU发出中断类型码为9的可屏蔽中断信息。CPU检测到该中断信息后,如果IF = 1,则响应中断,引发中断过程,转去执行int 9中断例程。
3. 执行 int 9中断例程
BIOS提供了int 9中断例程,来进行基本的键盘输入处理,主要工作如下:
读出60h端口中的扫描码;
如果是字符键的扫描码,就将该扫描码对应的字符码送入BIOS键盘缓冲区;如果是控制键,则转变为状态字节写入内存中存储状态字节的单元。
对键盘系统进行相关的控制,比如相关芯片发出应答。
BIOS键盘缓冲区是系统启动后,BIOS用于存放int 9中断例程接收的键盘输入的内存区。该内存可以存15个键盘输入,因为int 9 中断例程除了接收扫描码之外,还要产生和扫描码对应的字符码,所以在BIOS键盘缓冲区中,一个键盘输入用一个字单元存放, 高位字节存扫描码,低位字节存字符码。

编写 int 9中断例程:
编程:在屏幕中间依次显示“a” ~“z”,并可以让人看清,在显示的过程中,按下esc键后,改变显示的颜色。
1 | assume cs:code |
上面的程序执行过程中,我们无法看清屏幕上的显示,因为字母之间切换的太快,无法看清。
如何在每显示一个字母后,延迟一段时间,让人看清之后,再显示下个字母呢?我们让CPU执行一段时间的空循环,因为现在CPU的速度都非常快,所以循环的次数一定要大,如下:
1 | mov dx, 10h |
我们可以把这个程序写成一个子程序,现在我们的程序如下:
1 | assume cs:code |
显示”a” ~ “z”并且让人看清已经实现了,接下来怎么实现按下esc来改变颜色呢?
1.从端口60h读出键盘输入
1 | in al, 60h |
2.调用BIOS的int 9中断例程
这次我们不能之间使用int 9来调用,但是我们可以用别的指令来对int进行模拟
在假设要调用的中断例程入口地址在ds:0和ds:2的前提下,我们将int过程用下面几步模拟。
(1) 标志寄存器入栈;
(2) IF = 0, TF = 0
(3) CS, IP入栈
(4) (IP) = ((ds) * 16 +0), (CS) = ((ds) * 16 + 2)
对于(1)可用pushf实现
对于(2),可用以下指令实现:
1 | pushf |
则模拟int指令调用功能,调用入口地址在ds:0、ds:2中的中断例程的程序为:
1 | pushf |
3.如果是Esc的扫描码,改变显示的颜色后返回
完整的程序如下:
1 | assume cs:code |
安装新的int9中断例程
任务:安装一个新的int9中断例程
功能:在DOS下、按F1键后改变当前屏幕显示颜色,其他的键照常处理。
(1)改变屏幕的显示颜色
改变从b8000h开始的4000个字节的所有奇地址单元的内容,当前屏幕显示的颜色就会发生改变,程序如下:
1 | mov ax, 0b800h |
(2)其他键照常处理
可调用原int 9中断例程程序,来处理其他键盘的输入。
(3)原int9中断例程入口地址的保存。
要保存原int 9中断例程的入口地址,保存在0:200单元处,防止地址丢失。
(4)新int 9中断例程的安装
我们可将新的int 9中断例程安装在0:204处
1 | assume cs:code |
第16章 直接定位表
16.1 描述了单位长度的单元
前面我们,一直在代码端中使用标号来标记指令、数据、段的起始地址。比如如下:
1 | assume cs:code |
程序中,code、a、b、start、s都是标号。这些标号仅仅表示了内存单元的地址。
但是我们还可以用一种标号,不仅表示内存单元地址,还表示内存单元的长度,即表示在此标号的单元,是一个byte,还是word,还是dw。上面的程序可以这样写:
1 | assume cs:code |
code段使用的标号a,b后面没有:,它们是同时描述内存地址和内存单元长度的标号。
标号a,表示地址code:0,且后面的单元都是字节。
标号b,表示地址code:8,且后面的单元都是字。
16.2 在其他段中使用数据标号
一般来说,我们不在代码段定义数据,而是将数据定义在其他段中。在其他段中,我们也可以用数据标号来表示存储数据单元的地址和长度。
注意,后面加有“:”的地址标号只能在代码段中使用。
下面程序将a标号的8个数据累加,结果储存在b标号处的字中。
1 | assume cs:code, ds:data |
16.3 直接定址表
现在,我们讨论用查表的方法编写相关程序的技巧。
编写子程序,以16进制的形式在屏幕中间显示给定的字节型数据。
子程序如下:
1 | showbyte: |
16.4 程序入口地址的直接定址表
我们可以在直接定址表中存储子程序的地址,从而方便地实现不同的子调用。我们看以下问题:
实现一个子程序setscreem,为显示输出提供如下功能
清屏;
设置前景色;
设置背景色;
向上滚动一行。
入口参数说明如下:
用 ah 寄存器传递功能号:0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行;
对于1、2号功能,用al传递颜色值。
我们将这四个功能分别写成四个子程序。
1 | sub1: |
我们可以将这些子程序的入口地址储存在一个表中,他们在表中的位置和功能号相对应。
对应关系为:功能号 * 2 = 对应的功能子程序在地址表中的偏移。程序如下:
1 | setscreen: |
第17章
17.1 in9中断例程对键盘输入的处理
int9 中断例程对键盘输入的处理是:
从60h端口读出键盘输入的通码,检测状态字节是否有Shift、Ctrl等切换键按下。若没有,则将键盘输入的扫描码和通码输入缓冲区。如:键盘输入A,将A键的扫描码1eh和对应的ASCⅡ码61h写入键盘缓冲区。
1e61
17.2 使用int 16h 中断例程读取键盘缓冲区
int 16h中断例程包含一个最重要的功能就是从键盘缓冲区中读取一个键盘输入,该功能编号为0。
1 | mov ah, 0 |
结果:(ah) = 扫描码,(al) = ASCⅡ码
ah 中的内容为1Eh, al 中的内容为61h。从上面我们可以看出,int 16h 中断例程的0号功能,进行如下的工作。
(1) 检测键盘缓冲区中是否有数据;
(2) 没有则继续做第1步;
(3) 读取缓冲区第一个字单元中的键盘输入;
(4) 将读取的扫描码送入 ah,ASCII 码送入al;
(5) 将已读取的键盘输入从缓冲区中删除。
应用举例:
编程,接受用户的键盘输入,输入r,将屏幕上的字符设置成红色;输入g设置成绿色;输入b设置成蓝色。
1 | assume cs:code |
17.3 字符串的输入
最基本的字符串输入程序,要具备以下功能:
在输入的同时要显示这个字符串;
一般在输入回车符后,字符输入结束;
能够删除已经输入的字符。
子程序:字符栈的入栈、出栈和显示。
参数说明: (ah)=功能号,0表示入栈,1表示出栈,2表示显示:
ds:si 指向字符栈空间;
对于0号功能: (al)=入栈字符;
对于1号功能:(al)=返回的字符;
对于2号功能: (dh)、(dl)=字符串在屏幕上显示的行、列位置。
1 | charstack: |
下面写出完整的接收字符串的子程序,如下:
1 | getstr: |
17.4 应用int 13h中断例程对磁盘进行读写
以3.5英寸软盘为例,3.5 英寸软盘分为上下两面,每面有80个磁道,每个磁道又分为18个扇区,每个扇区的大小为512个字节。
则: 2面 * 80 磁道 * 18 扇区 * 512 字节=1440KB~1.44MB
BIOS通过了对扇区进行读写的中断例程,我们可以通过调用BIOS中断例程里访问磁盘。
BIOS提供访问磁盘的中断例程为int 13h。读取 0 面 0 道 1 扇区的内容到0:200的程序如下:
1 | mov ax, 0 |
返回参数:
操作成功:(ah) = 0,(al) = 读入的扇区数
操作失败:(ah) = 出错代码
接口部分:
5.2 RAM 随机存储器
5.2.1 SRAM 静态 RAM
SRAM 的特点
Static RAM, 静态随机存储器
特点:
- 速度快、状态稳定、不需刷新、单元复杂、功耗大、价格高、常见于高速缓存Cache
SRAM 写法:
如:2114:1K x 4
表示:
有1K个存储单元
每个单元4bit
总容量 = 1K x 4 bit = 500B 一个字节八个bit
常考:
芯片的容量怎么算?
- 单元数 x 每单元位数,再写成字节
地址线根数 = log2(单元数)
数据线跟数 = 每个单元的位数
5.2.2 DRAM 动态 RAM
Dynamic RAM,动态随机存储器
特点:
- 速度比SRAM慢、用电容存、状态不稳、要定时刷新、集成度高、功耗小价格低、常见于主存
5.2.3 DRAM 为什么要刷新?
DRAM单元靠电容也没有电荷表示0/1,但问题是:电容会漏电。
所以DRAM不是写进去就稳定,需要定期刷新。
刷新方式:异步刷新:
以2164A为例:
刷新间隔:2ms
2164A 共 128周期
每隔:
2ms / 128 = 15.6 us 刷新一行。
5.3 ROM
5.3.1 核心特点:
只读
掉电后内容不丢失
存放BIOS、固定程序常量等
5.3.2 EPROM 27128
27128 = 16K x 8
引脚理解:
地址线 14根:A13 - A0 选择芯片内部的哪个单元
数据线 8根 :D7 - D0 用来输出/编程输入数据
CE:片选,决定这个芯片是否被选中
OE:输出允许,读出是数据是否出现在数据线上
PGM:编程控制
VPP:编程电压
VCC/GND:电源和地
5.3.3 EEPROM 2817A
特点:
可电擦除
可电写入
编程前能自动擦除要写入的单元
5.4 存储器和CPU的连接
5.4.1 存储器的接口设计要考虑什么?
1 | 存储器和CPU连接,要考虑: |
5.4.2 地址线:高位片选,低位片内寻址
1 | 低位地址线: |
5.4.3 片选信号CS/CE
CPU地址空间很大,但是一片芯片容量有限
所以访问某个地址的时候,系统要先判断:这个地址属于哪一片芯片?
选中芯片的信号就叫:
1 | 片选信号:CS 或 CE |
常见的片选信号是低电平有效:
1 | CE = 0: 芯片被选中 |
5.4.4 74LS138 译码器
1 | 74LS138 = 3-8译码器 |
例如输入为:1 0 0 对应十进制数为4 -> Y4 = 0,其他均为1
5.4.5 芯片扩展
1. 位扩展:
2. 字扩展
3. 字位扩展
5.4.6 三种片选方法
1. 线选法
用某几根高位地址线直接作为片选信号。
电路简单,但是很多高位地址会没有参与编码,造成地址重叠和地址空间浪费。
2. 全译码法
所以高位地址全部参与编码
不会有地址重叠,但是译码电路复杂
3. 部分译码法
只让一部分高位地址参与译码
比全译码简单,但是仍然可能产生地址重叠
6.1 I/O接口
6.1.1 为什么需要I/O接口?
CPU和存储器比较合拍,但是CPU和外设差异太大了。
1 | CPU: |
所以在CPU和外设之间要加:I/O接口电路。
I/O接口电路是外设和计算机之间传送信息的交接部件,每个外设都要通过接口电路才能和主机相连。
6.1.2 I/O接口的功能
1 | 1. 数据缓冲 |
6.1.3 I/O端口
CPU和外设交换的信息主要有三类:
1 | 1. 数据信息 |
所以端口也分为三类
数据端口:存放输入/输出的数据
状态端口:让CPU读取外设的状态
控制/命令端口:CPU向接口发命令
6.1.4 常见的状态位
Ready:准备好。输入的时候有数据等待CPU读,输出的时候表示输出缓冲区为空,可以接受新数据。
Busy:忙。外设正在工作,暂时不能接受新数据。
Error:错误。数据传送过程中出错了。
6.1.5 I/O 端口寻址方式
1. 存储器映像寻址
1 | I/O端口和内存统一编址。 |
优点:访存指令都能访问I/O端口缺点:占用内存地址空间
2. I/O单独编址
1 | I/O端口单独拥有地址空间。CPU用专门的 IN / OUT 指令访问。 |
8086 系统采用 I/O 单独编址方式。
6.1.6 CPU和外设的数据传送方式
1. 程序控制方式
分两种:
无条件传送:默认外设随时准备好,准备IN/OUT
条件传送/查询方式:CPU先读状态口,确认Ready还是Busy,再传送数据
2. 中断方式
CPU平时做自己的事情
外设准备好之后发中断请求
CPU响应中断,执行中断服务程序完成一次数据传送
3. DMA方式
DMA = Direct Memory Access
之间从存储器中读取
特点:
CPU让出总线控制权
DMA控制器接管地址总线、数据总线、控制总线
外设和内存直接批量传送数据
传完后归还总线
6.2 8255A工作原理
6.2.1 什么是8255A?
8255A是可编程并行I/O接口芯片
它可以通过编程工作在三种方式:
方式0:基本输入输出
方式1:选通输入输出
方式2:双向总线方式
6.2.2. 内部结构
8255A内部包括:
数据端口A,B,C
A组和B组控制逻辑
数据总线缓冲器
读写控制逻辑
1. 三个端口:
A口:8位,PA7 ~ PA0
B口:8位,PB7 ~ PB0
C口:8位,PC7 ~ PC0
C口比较特殊,可以拆成:
C高:PC7 ~ PC4
C低:PC3 ~ PC0
2. A组和B组
A组:管理A口和C高
B组:管理B口和C低
6.2.3 端口地址选择
8255A用A1A0选择内部端口:
| A0A1 | 选择 |
|---|---|
| 00 | A口 |
| 01 | B口 |
| 10 | C口 |
| 11 | 控制口 |
若8255A的基地址为60h,则A、B、C、控制口分别为60h、61h、62h、63h。
在 8086 的 16 位系统中,如果 8255A 的 D7~D0 接低 8 位数据总线,则通常用偶地址访问。例如基地址 F0H 时,A/B/C/控制口分别是 F0H、F2H、F4H、F6H。
5.4-存储器的连接(1).pptx
Presentation
6.1-IO接口.pptx
Presentation
6.2-8255A的原理.pptx
Presentation
6.3-8255A的应用举例.pptx
Presentation
5.2+5.3-RAM&ROM存储器.pptx
Presentation
根据ppt带着我详细的学一下这几章的内容,格式用md,我方便做笔记
Thought for 43s
我先按本科《微型计算机原理与接口技术》期末复习 + 真正理解电路/编程思路来带你学。我们这批 PPT 主要是:
第5章 存储器- 5.2 RAM:SRAM、DRAM- 5.3 ROM:EPROM、EEPROM- 5.4 存储器与CPU的连接第6章 I/O接口与8255A- 6.1 I/O接口- 6.2 8255A工作原理- 6.3 8255A应用举例
下面先给你一版可直接做笔记的总框架,然后我们从 5.2 RAM 开始慢慢啃。
第5章、第6章学习总路线
一句话总览
第5章解决的问题:CPU怎样和“存储芯片”连接,并正确读写数据?第6章解决的问题:CPU怎样和“外设”连接,并通过8255A这种接口芯片输入/输出数据?
存储器连接重点是:地址线、数据线、控制线、片选信号。PPT 里强调,存储器要和 CPU 的地址、数据、控制总线正确连接,并考虑 CPU 总线负载、存储器速度、地址分配、片选和控制信号连接。
I/O 接口重点是:CPU 和外设速度、电平、格式、时序都不一样,所以中间必须有接口电路。PPT 中把 I/O 接口功能归纳为数据缓冲、电平转换、信息格式转换、时序控制、地址译码和读写/中断控制等。
5.2 RAM 随机存储器
5.2.1 SRAM 静态 RAM
1. SRAM 的特点
SRAM = Static RAM,静态随机存储器特点:- 速度快- 状态稳定- 不需要刷新- 单元电路复杂- 集成度低- 功耗较大- 价格较高- 常用于高速缓存 Cache
PPT 中明确给出 SRAM“速度快,状态稳定”,但“位单元电路复杂、集成度低、功耗较大、价格偏高”,主要用于高速缓存。
2. 常见 SRAM 芯片
2114:1K × 46116:2K × 86232:4K × 86264:8K × 862256:32K × 864C512:64K × 8
这里的写法非常重要:
2K × 8 表示:- 有 2K 个存储单元- 每个存储单元 8 位- 总容量 = 2K × 8 bit = 2KB
考试里经常考:
芯片容量 = 单元数 × 每单元位数地址线根数 = log2(单元数)数据线根数 = 每单元位数
例如:
6116 = 2K × 82K = 2048 = 2^11所以地址线需要 11 根:A10 ~ A0每个单元 8 位所以数据线需要 8 根:I/O7 ~ I/O0
PPT 里 6116 的容量是 2K×8bit,即 2048 字节,并列出了地址线 A10~A0、数据线 I/O7~I/O0 等主要引脚。
5.2.2 DRAM 动态 RAM
1. DRAM 的特点
DRAM = Dynamic RAM,动态随机存储器特点:- 速度比 SRAM 慢- 用电容存储电荷- 状态不稳定- 必须定时刷新- 单元电路简单- 集成度高- 功耗小- 价格低- 常用于主存/内存条
PPT 中给出 DRAM 的典型刷新间隔为 2ms,并指出它主要用于构造内存条。
2. SRAM 和 DRAM 对比
| 对比项 | SRAM | DRAM |
|---|---|---|
| 存储原理 | 触发器 | 电容 |
| 是否刷新 | 不需要 | 需要 |
| 速度 | 快 | 较慢 |
| 集成度 | 低 | 高 |
| 功耗 | 较大 | 较小 |
| 成本 | 高 | 低 |
| 典型用途 | Cache | 主存 |
记忆口诀:
S = Stable = 稳定,不刷新,贵且快D = Dynamic = 动态,要刷新,便宜容量大
5.2.3 DRAM 为什么要刷新?
DRAM 单元靠电容有没有电荷表示 0/1。问题是:电容会漏电。
所以 DRAM 不是写进去就永久稳定,而是要周期性把数据读出、放大、再写回去,这就叫刷新。
PPT 里 2164A 的刷新操作是:刷新时只接收行地址,选中若干行单元,把信息送到读出放大器放大后再写回原单元;刷新时 DRAM 不能被读写。
刷新方式:异步刷新
典型刷新间隔:2ms2164A 共 128 个刷新周期每隔:2ms / 128 = 15.6μs刷新一行。
PPT 中也给出异步刷新按 15.6μs 间隔依次刷新,并由专门 DRAM 控制器控制。
5.3 ROM 只读存储器
5.3.1 ROM 的核心特点
ROM = Read Only Memory特点:- 正常工作时主要读出- 掉电后内容不丢失- 常用于存放 BIOS、固定程序、表格、常量等
你可以把 RAM 和 ROM 这样区分:
RAM:运行时临时放数据,掉电丢失ROM:长期保存固定内容,掉电不丢
5.3.2 EPROM 27128
PPT 重点讲了 EPROM 27128。它的容量是:
27128 = 16K × 8
所以:
16K = 2^14地址线:14 根,A13 ~ A0数据线:8 根,D7 ~ D0
PPT 中 27128 内部包括存储阵列、X/Y 译码器、输出允许/片选/编程逻辑、数据输出缓冲器;其容量为 16K×8,A13~A0 共 14 根地址线,D7~D0 为 8 位数据线。
EPROM 的常见引脚理解
A13 ~ A0:地址线,用来选择芯片内部哪个单元D7 ~ D0:数据线,用来输出/编程输入数据CE:片选,决定这片芯片是否被选中OE:输出允许,读出时让数据出现在数据线上PGM:编程控制VPP:编程电压VCC/GND:电源和地
5.3.3 EEPROM 2817A
EEPROM = Electrically Erasable Programmable ROM特点:- 可电擦除- 可电写入- 编程前能自动擦除要写入的单元
PPT 中 EEPROM 2817A 容量为 2KB,存取时间 150ns,写入时间和擦除时间约 10ms。
5.4 存储器与 CPU 的连接
这部分是第5章最容易出大题的地方。
5.4.1 存储器接口设计要考虑什么?
存储器与CPU连接时,要考虑:1. 地址总线怎么连2. 数据总线怎么连3. 控制总线怎么连4. CPU负载能力是否够5. 存储器速度是否跟得上CPU时序6. 地址空间如何分配7. 片选信号如何产生
PPT 中明确说,要考虑 CPU 总线负载能力、CPU 时序与存储器存取速度配合、地址分配和片选、控制信号连接。
5.4.2 地址线:高位片选,低位片内寻址
这是本节的灵魂。
低位地址线:接到存储芯片的地址引脚,用来选择芯片内部哪个单元。高位地址线:送入译码器,用来产生片选信号,决定选中哪一片芯片。
PPT 中说,通常 CPU 地址信息的高位用来生成片选信号,低位直接连到芯片地址线上,实现片内寻址。
5.4.3 片选信号 CS/CE
CPU 地址空间很大,但一片芯片容量有限。
所以访问某个地址时,系统要先判断:
这个地址属于哪一片芯片?
选中芯片的信号就叫:
片选信号:CS 或 CE
常见片选信号是低电平有效:
CE = 0:芯片被选中CE = 1:芯片不工作
5.4.4 74LS138 译码器
74LS138 = 3-8译码器输入:C B A 三位二进制输出:Y0 ~ Y7 八个输出特点:某一时刻只有一个输出为低电平
PPT 中说 74LS138 输入 3 位二进制码,在 8 个输出中产生 1 个低电平片选信号。
可以这样记:
CBA = 000 -> Y0 = 0CBA = 001 -> Y1 = 0CBA = 010 -> Y2 = 0…CBA = 111 -> Y7 = 0
5.4.5 存储空间扩展
1. 位扩展
位扩展:增加每个存储单元的位数
比如 CPU 数据总线是 8 位,但芯片是:
64K × 1
一片只能提供 1 位数据,所以要 8 片并联:
8片 64K × 1 -> 64K × 8
PPT 中的例子就是用 8 片 64K×1 芯片扩展成 64KB 存储器,各片地址线并接,各 I/O 脚分别接 D7~D0。
2. 字扩展
字扩展:增加存储单元个数,也就是扩大地址范围
例如:
16K × 8 -> 64K × 8
一片是 16K,要变成 64K:
64K / 16K = 4所以需要 4 片。
PPT 中例 5.3 正是用 4 个 16K×8 芯片字扩展为 64K×8,并用 2-4 译码器产生片选信号。
3. 字位扩展
字位扩展 = 位数不够 + 字数不够
例如:
用 1K × 4 构成 4K × 8
步骤:
第一步:位扩展2片 1K×4 -> 1K×8第二步:字扩展4组 1K×8 -> 4K×8
PPT 例 5.4 正是用 1K×4 的 2114 构成 4K×8:先 2 片并成 1KB,再 4 组字扩展。
5.4.6 三种片选方法
1. 线选法
用某几根高位地址线直接作为片选信号。
优点:
电路简单
缺点:
很多高位地址没有参与译码会造成地址重叠地址空间浪费
PPT 中线选法使用某 1 位高位地址做片选,电路简单但空间浪费大,会导致地址重叠和地址不连续。
2. 全译码法
所有高位地址线都参与译码。
优点:
每个存储单元地址唯一不存在地址重叠
缺点:
译码电路复杂
PPT 中全译码法定义为全部高位地址参与译码,使每个存储单元地址唯一,不存在地址重叠,但译码电路复杂。
3. 部分译码法
只让一部分高位地址参与译码。
特点:
比全译码简单但仍可能产生地址重叠
PPT 中部分译码法只对高位地址中的某几位译码,未参与译码位可以是 0 或 1,因此每个存储单元可能对应多个地址。
6.1 I/O接口
6.1.1 为什么需要 I/O 接口?
CPU 和存储器比较“合拍”,但 CPU 和外设差异太大。
CPU:- 速度快- 电平标准统一- 数据格式规整- 时序严格外设:- 速度慢- 种类多- 电平可能不同- 数据格式可能不同- 工作时序不统一
所以中间要加:
I/O接口电路
PPT 中说,I/O 接口电路是外设与计算机之间传送信息的交接部件,每个外设都要通过接口电路才能与主机相连。
6.1.2 I/O接口的功能
1. 数据缓冲 解决CPU快、外设慢的问题。2. 电平转换 解决TTL、RS-232等电平不一致问题。3. 信息格式转换 例如模拟量/数字量转换,串行/并行转换。4. 时序控制 通过状态、应答、中断等信号协调CPU和外设。5. 地址译码 判断CPU当前访问的是哪个I/O端口。6. 提供读/写、中断等控制逻辑
6.1.3 I/O端口
CPU 和外设交换的信息主要有三类:
1. 数据信息2. 状态信息3. 控制信息
所以端口也分三类:
| 端口类型 | 作用 |
|---|---|
| 数据端口 | 存放输入/输出数据 |
| 状态端口 | 让 CPU 读取外设状态 |
| 控制/命令端口 | CPU 向接口发命令 |
PPT 中把 I/O 端口定义为接口电路中相关寄存器及控制逻辑,CPU 可直接读写端口信息。
6.1.4 常见状态位
Ready:准备好。输入时表示有数据等CPU读;输出时表示输出缓冲器空,可以接收新数据。Busy:忙。表示外设正在工作,暂时不能接收新数据。Error:错误。表示传送过程中发生错误。
6.1.5 I/O端口寻址方式
1. 存储器映像寻址
I/O端口和内存统一编址。
特点:
优点:访存指令都能访问I/O端口缺点:占用内存地址空间
2. I/O单独编址
I/O端口单独拥有地址空间。CPU用专门的 IN / OUT 指令访问。
PPT 中说 8086 系统采用 I/O 单独编址方式。
6.1.6 CPU与外设的数据传送方式
1. 程序控制方式
又分两种:
无条件传送:默认外设随时准备好,直接 IN/OUT。条件传送 / 查询方式:CPU先读状态口,确认Ready/Busy,再传送数据。
PPT 中说明程序控制方式由程序完成,分为无条件传送和条件传送;条件传送要先读取状态口,反复检测外设是否准备好。
2. 中断方式
CPU平时做自己的事。外设准备好后发中断请求。CPU响应中断,执行中断服务程序完成一次数据传送。
PPT 中提到查询方式会让 CPU 大量等待,而中断方式下 CPU 平时执行主程序,外设准备好后再请求 CPU 服务。
3. DMA方式
DMA = Direct Memory Access直接存储器存取
特点:
CPU让出总线控制权DMA控制器接管地址总线、数据总线、控制总线外设和内存直接批量传送数据传完后归还总线
PPT 中 DMA 控制器可以给出内存地址、修改地址指针、设定传送字节数,并向内存和外设发读写控制信号。
6.2 8255A 工作原理
6.2.1 8255A是什么?
8255A = 可编程并行I/O接口芯片PPI = Programmable Peripheral Interface
它可以通过编程工作在三种方式:
方式0:基本输入输出方式1:选通输入输出方式2:双向总线方式
PPT 中明确 8255A 是通用可编程并行 I/O 接口芯片,可通过编程工作于 3 种数据传输方式。
6.2.2 8255A内部结构
8255A内部主要包括:1. 数据端口A、B、C2. A组和B组控制逻辑3. 数据总线缓冲器4. 读/写控制逻辑
PPT 中给出 8255A 有端口 A/B/C,其中 C 口可分成上半部和下半部,还有 A组/B组控制逻辑、数据总线缓冲器、读写控制逻辑。
6.2.3 三个端口
A口:8位,PA7 ~ PA0B口:8位,PB7 ~ PB0C口:8位,PC7 ~ PC0
C口特殊:
C口可以拆成:- C高:PC7 ~ PC4- C低:PC3 ~ PC0C口还常用作A口、B口的联络/状态控制信号。
6.2.4 A组和B组
A组:- 管理A口- 管理C口高4位 PC7 ~ PC4B组:- 管理B口- 管理C口低4位 PC3 ~ PC0
这点很重要,因为控制字里会分别设置 A组、B组。
6.2.5 端口地址选择
8255A 用 A1A0 选择内部端口:
| A1A0 | 选择 |
|---|---|
| 00 | A口 |
| 01 | B口 |
| 10 | C口 |
| 11 | 控制口 |
PPT 中给出:若 8255A 基地址为 60H,则 A口、B口、C口、控制口分别为 60H、61H、62H、63H。
在 8086 的 16 位系统中,如果 8255A 的 D7~D0 接低 8 位数据总线,则通常用偶地址访问。例如基地址 F0H 时,A/B/C/控制口分别是 F0H、F2H、F4H、F6H。
6.2.6 8255A工作方式
方式0:基本输入输出
适合简单I/O不需要应答信号A口、B口可作8位输入/输出C高、C低可作4位输入/输出输出可锁存输入一般不锁存
PPT 中说方式0适用于不需要应答信号的简单 I/O,A口、B口作8位端口,C高和C低作两个4位端口或合成8位端口。
方式1:选通输入/输出
适合需要握手信号的I/OA口、B口作为数据口C口部分引脚作为联络信号支持中断请求
PPT 中方式1又称选通输入/输出方式,A口、B口作数据口,PC2~PC0、PC5~PC3 用作联络信号。
典型联络信号:
STB:选通信号IBF:输入缓冲器满OBF:输出缓冲器满ACK:外设应答INTR:中断请求INTE:中断允许
方式2:双向总线方式
只有A口支持方式2A口可双向传送数据输入、输出都可锁存C口提供联络信号
PPT 中说方式2也称双向总线方式,只有 A口支持,A口既能输入也能输出。
6.3 8255A应用举例
6.3.1 例1:开关状态检测 + LED显示
题意:
8个开关 K7 ~ K08个LED LED7 ~ LED0要求:开关断开 -> 对应LED亮开关闭合 -> 对应LED灭
硬件思路:
A口输入:接开关B口输出:接LEDC口不用
PPT 中例1就是 A口输入接 K7~K0,B口输出接 LED7~LED0,端口地址为 F0H、F2H、F4H、F6H,分别对应 A口、B口、C口、控制口。
控制字:
A口方式0输入B口方式0输出C口不用控制字 = 10010000B = 90H
程序逻辑:
MOV DX, 0F6HMOV AL, 10010000BOUT DX, ALTEST_IT: MOV DX, 0F0H IN AL, DX MOV DX, 0F2H OUT DX, AL CALL DELAY JMP TEST_IT
核心不是背程序,而是看懂:
初始化8255A -> 从A口读开关 -> 向B口输出 -> LED显示 -> 循环
6.3.2 例2:开关状态用七段LED显示
题意:
A口接4个开关 K3 ~ K0B口接七段LED显示器4位开关共有16种状态,显示0~F
PPT 中 A口方式0输入,B口方式0输出;PB0~PB6 接 a~g 段,通过 74LS04 反相驱动。
七段码表:
TABLE DB 40H,79H,24H,30H,19H,12H,02H,78H DB 00H,18H,80H,03H,43H,21H,06H,0EH
程序核心:
IN AL, 60H ; 读A口AND AL, 0FH ; 只取低4位MOV BX, OFFSET TABLEXLAT ; 查表OUT 61H, AL ; 输出七段码
这里最关键的是:
开关状态不是直接输出到七段LED。而是:开关状态 -> 作为表下标 -> 查七段码 -> 输出到B口
本轮小结
第5章核心:1. RAM分SRAM和DRAM2. SRAM快、不刷新、贵,用于Cache3. DRAM慢、要刷新、便宜,用于主存4. ROM掉电不丢,EPROM/EEPROM可编程5. 存储器连接重点是地址线、数据线、控制线、片选6. 高位地址译码片选,低位地址片内寻址7. 扩展方式:位扩展、字扩展、字位扩展8. 译码方式:线选、全译码、部分译码第6章核心:1. I/O接口解决CPU与外设速度、电平、格式、时序不匹配2. 端口分数据口、状态口、控制口3. 传送方式:程序控制、中断、DMA4. 8255A有A/B/C三个端口5. 8255A有方式0、方式1、方式26. 应用题一般是:确定端口方向 -> 写控制字 -> IN读 -> OUT写
先检查一个小问题,看看第5章地基稳不稳:
某 SRAM 芯片标为 8K × 8,它需要多少根地址线?多少根数据线?
你先答这个,我们再继续把 “存储器连接题怎么做” 细讲一遍。
例1我没太看懂啊
Thought for 22s
可以,这个例1其实就一句话:
8255A 把“开关状态”从 A口读进来,再原封不动从 B口送出去,让 LED 显示。
你先别管图,我们把它拆成 4步。
例1:8个开关控制8个LED
- 题目要干什么?
有 8 个开关:K7 ~ K0有 8 个 LED:LED7 ~ LED0要求:- 开关断开 -> 对应 LED 亮- 开关闭合 -> 对应 LED 灭
PPT 里这个例子就是“不断检测 K7~K0 的通断状态,并显示在 LED7~LED0 上”。
8255A 有 A、B、C 三个端口。
这个题里:
A口:输入口- PA7 ~ PA0 接 8 个开关 K7 ~ K0- 作用:读开关状态B口:输出口- PB7 ~ PB0 接 8 个 LED- 作用:控制 LED 亮灭C口:不用
所以电路逻辑是:
开关 K7K0 ↓8255A A口输入 ↓CPU读入AL ↓CPU再输出AL ↓8255A B口输出 ↓LED7LED0
一句人话:A口负责“看”,B口负责“说”。
8255A 上电后不知道 A口、B口该输入还是输出,所以 CPU 要先写一个控制字告诉它:
A口:方式0输入B口:方式0输出C口:不用
控制字:
MOV AL, 10010000BOUT 0F6H, AL
拆开看:
10010000BD7 = 1:这是“方式选择控制字”D6D5 = 00:A组方式0D4 = 1:A口输入D3 = 0:C口高4位输出/不用D2 = 0:B组方式0D1 = 0:B口输出D0 = 0:C口低4位输出/不用
所以它的含义就是:
把8255A设置成:A口输入,B口输出,方式0。
PPT 中也写了:A口方式0输入,B口方式0输出,C口未用,控制字为 10010000。
PPT 给出本例中 8255A 的 4 个端口地址:
| 端口 | 地址 |
|---|---|
| A口 | F0H |
| B口 | F2H |
| C口 | F4H |
| 控制口 | F6H |
也就是说:
0F0H -> A口0F2H -> B口0F6H -> 控制口
所以程序里:
MOV DX, 0F6HOUT DX, AL
意思是:
把控制字写入控制口,初始化8255A。
然后:
MOV DX, 0F0HIN AL, DX
意思是:
从A口读开关状态到AL。
再然后:
MOV DX, 0F2HOUT DX, AL
意思是:
把AL里的开关状态输出到B口,让LED显示。
PPT 程序也正是这个流程:先向 F6H 写控制字,再从 F0H 读 A口,最后向 F2H 写 B口。
因为这个硬件刚好满足:
开关断开 -> A口读到 1开关闭合 -> A口读到 0B口输出 1 -> LED亮B口输出 0 -> LED灭
题目要求是:
开关断开 -> LED亮开关闭合 -> LED灭
完全对应上了!
所以不需要取反,不需要判断,直接:
IN AL, DX ; 读开关OUT DX, AL ; 输出给LED
就行。
举个例子:
假设 8 个开关状态读入后:AL = 10110010B
那么输出到 B口后:
PB7~PB0 = 10110010B
于是:
值为1的那些LED亮值为0的那些LED灭
也就是 LED 状态和开关断开/闭合状态一一对应。
翻译:
告诉8255A:A口做输入,B口做输出。
TEST_IT: MOV DX, 0F0H IN AL, DX
翻译:
从A口读取8个开关的状态,放到AL里。
MOV DX, 0F2H OUT DX, AL
翻译:
把刚才读到的8位状态,送到B口控制8个LED。
CALL DELAY_20S JMP TEST_IT
翻译:
延时一下,然后继续检测。
所以完整逻辑就是:
初始化8255A↓读A口开关↓写B口LED↓延时↓回去继续读
你抓住这个模型就行
A口 = 输入 = 看开关B口 = 输出 = 控制LED控制口 = 配置8255A怎么工作
程序的骨架:
写控制字循环: 从A口读 向B口写 延时 跳回循环
我问你一个小检查:
在这个例子里,IN AL, DX 执行时,DX = 0F0H,那 CPU 读的是 A口、B口、C口还是控制口?
这个控制字怎么得到的
Thought for 15s
对,这个点特别关键。8255A 的控制字不是“算”出来的,是按位填表填出来的。
PPT 里说:方式选择控制字写入控制口,用来定义各端口工作方式,并且要求 D7=1;D6D5 选 A 口方式,D2 选 B 口方式,D4D3D1D0 分别决定 A口、C高、B口、C低是输入还是输出,且 1=输入,0=输出。
8255A 方式选择控制字格式
D7 D6 D5 D4 D3 D2 D1 D0
每一位含义如下:
| 位 | 含义 | 本题怎么填 |
|---|---|---|
| D7 | 方式选择控制字标志 | 必须为 1 |
| D6D5 | A组工作方式 | 方式0,所以 00 |
| D4 | A口方向 | A口输入,所以 1 |
| D3 | C口高4位方向 | C口不用,清0,所以 0 |
| D2 | B组工作方式 | 方式0,所以 0 |
| D1 | B口方向 | B口输出,所以 0 |
| D0 | C口低4位方向 | C口不用,清0,所以 0 |
6.3 8255A应用举例
6.3.1 例1:开关状态检测 + LED显示
1 | 8个开关 K7 ~ K0 |
硬件思路:
1 | A口输入:开关 |
控制字:
1 | A口方式0输入 |
程序逻辑:
1 | mov dx, 0f6h |