各种存储器都和 CPU 的地址线、数据线、控制线相连。CPU 把它们当做内存来对待,看做一个由若干存储单元组成的逻辑存储器。这个逻辑存储器叫做内存地址空间。
和 CPU 通过总线相连的芯片除各种存储器外,还有
1、各种接口卡(网卡、显卡)上的接口芯片,它们控制接口卡进行工作;
2、主板上的接口芯片,CPU 通过它们对部分外设进行访问;
3、其他芯片,用来存储相关的系统信息,或进行相关输入输出处理;
这些芯片中,都有一组可以由CPU读写的寄存器。这些寄存器物理上可能处于不同的芯片中,但是
1、都和CPU的总线相连,这种连接是通过它们所在的芯片进行的;
2、CPU对它们进行读或写的时候都通过控制线向它们所在的芯片发出端口读写命令。
从CPU的角度,将这些寄存器都当做端口,对他们进行统一编址,从而建立了一个统一端口地址空间。每一个端口在地址空间中都有一个地址。
CPU可以直接读写3个地方的数据:
1、CPU 内部的寄存器
2、内存单元
3、端口
端口的读写
CPU最多可以定位 64K 个不同的端口。端口地址的范围为 0~65535。
端口的读写指令只有两条:in 和 out ,分别用于从端口读取数据和往端口写入数据。
CPU 执行内存访问指令和端口访问指令的时候,总线上的信息: 1、访问内存: mov ax , ds:[8] ; 假设执行前(ds)=0 执行时与总线相关的操作: ① CPU通过地址线将地址信息8发出; ② CPU通过控制线发出内存读命令,选中存储器芯片,并通知它,将要从中读取数据; ③ 存储器将8号单元中的数据通过数据线送入 CPU。 2、访问端口: in al , 60h ; 从60h号端口读入一个字节 执行时与总线相关的操作: ① CPU通过地址线将地址信息60h发出; ② CPU通过控制总线发出端口读命令,选中端口所在芯片,并通知它,将要从中读取数据; ③ 端口所在的芯片将60h端口中的数据通过数据总线送入CPU。 注意:in 和 out 指令中,只能使用 ax 或 al 来存放从端口中读入的数据或要发送到端口中的数据。访问8位端口时用 al ,访问16位端口时用 ax。 |
对 0~255 以内的端口进行读写时: in al , 20h ; 从20h端口读入一个字节 out 20h , al ; 往20h端口写入一个字节 对 256~65535 的端口进行读写,端口号放在dx中: mov dx , 3f8h ; 将端口号3f8h送入dx in al , dx ; 从3f8 端口读入一个字节 out dx , al ; 向 3f8 端口写入一个字节 |
CMOS RAM 芯片(Complementary metal oxide semiconductor RAM chip)
CMOS RAM 芯片,一般简称 CMOS。(互补金属氧化物半导体)
1、包含一个实时钟和一个有128个存储单元的RAM存储器(早期的计算机为64个字节)。
2、该芯片靠电池供电。所以,关机后其内部的实时钟仍可正常工作,RAM中的信息不丢失。
3、128 个字节的RAM中,内部实时钟占用 0~0dh 单元来保存时间信息,其余大部分单元用于保存系统配置信息,供系统启动时 BIOS 程序读取。BIOS 也提供了相关的程序,使我们可以在开机的时候配置 CMOS RAM 中的系统信息。
4、该芯片内部有两个端口,端口地址为 70h 和 71h。CPU 通过这两个端口来读写 CMOS RAM。
5、70h 为地址端口,存放要访问的CMOS RAM单元的地址;71h 为数据端口,存放从选定的 CMOS RAM 单元中读取的数据,或要写入到其中的数据。
CPU 对CMOS RAM的读写分两步进行,eg: 读 CMOS RAM的2号单元: ① 将 2 送入端口 70h ② 从71h 读出 2 号单元的内容 |
; 编程:读取 CMOS RAM 的2号单元的内容。 assume cs:code
code segment
start: mov al , 2
out 70h , al ; 地址端口送入2,表示要访问的单元地址
in al , 71h ; 数据端口读出选定端口的数据
mov ax , 4c00h
int 21h
code ends
end start
|
; 编程:向 CMO RAM 的2号单元写入 0。 assume cs:code
code segment
start: mov al , 2
out 70h , al ; 地址端口送入2,表示要访问的单元地址
mov al , 0
out 71h , al ; 将al中的数据0送到71h数据端口
mov ax , 4c00h
int 21h
code ends
end start
|
shl 和 shr 指令
shl 和 shr 是逻辑移位指令
shl 逻辑左移指令: 1、将一个寄存器或内存单元中的数据向左移位; 2、将最后移出的一位写入CF中; 3、最低位用0补充。 mov al , 01001000b shl al , 1 (al)=10010000b,CF=0。 当移动位数大于1时,必须将移动位数放在 cl 中。 mov al , 01010001b mov cl , 3 shl al , cl (al)=10001000b,最后移出的一位是0,CF=0 |
shr 逻辑右移指令: 1、将一个寄存器或内存单元中的数据向右移位; 2、将最后移出的一位写入CF中; 3、最高位用0补充。 mov al , 10000001b shr al , 1 (al)=01000000b,CF=1。 mov al , 01010001b mov cl , 3 shr al , cl (al)=00001010b,最后移出的一位是0,CF=0 |
编程:用加法和移位指令计算(ax)=(ax)*10 提示:(ax)*10=(ax)*2+(ax)*8 |
assume cs:code , ds:data ; 没什么用,ds该是啥还是啥所以一般都不写了
data segment
dw 3
data ends
code segment
start: mov ax , data
mov ds , ax
mov bx , 0
mov ax , [bx]
mov bx , ax
shl ax , 1
mov cl , 3
shl bx , cl
add ax , bx
mov ax , 4c00h
int 21h
code ends
end start
|
CMOS RAM 中存储的时间信息
CMOS RAM 中存放着当前的时间:年、月、日、时、分、秒。这6个信息的长度都为 1 个字节(6个信息一共12个单元),存放单元为:
秒:0 | 分:2 | 时:4 | 日:7 | 月:8 | 年:9 |
// 这些数据都是以 BCD 码的方式存放的。所以时分秒和年要两个单元(8位),月日只要一个单元(4位);其中年值存放最后两位,最大99
BCD 码是以 4 位二进制数表示十进制数码的编码方法;
1 == 0001 , 26 == 0010 0110
一个字节可以表示两个 BCD 码。CMOS RAM 存储时间信息的单元中,存储了用两个 BCD 码表示的两位十进制数,高4位的BCD码表示十位,低4位的BCD码表示个位。eg: 00010100b表示14