在计算机结构中,cpu可以直接读写以下3个地方的数据:
1】cpu内部寄存器; ->比如:mov ax,0
2】内存单元; ->比如:mov ax,ds:[0]
3】端口;
1.关于内存地址空间
计算机结构中有多个储存芯片;比如主存储器、显卡、网卡等;
这些储存器通过总线与cpu相连;
cpu对它们进行读写时,通过控制线发出内存读写命令;
也就是说,cpu在控制存储器时,将它们看做一个由若干存储单元组成的逻辑储存器;
这个逻辑存储器就是我们所说的内存地址空间;
2.关于端口
在计算机结构中,和cpu通过总线相连的芯片除了各种储存器外,还有3种芯片:
1】各种接口卡上的接口芯片 ->用来控制接口卡进行工作;比如网卡、显卡
2】主板上的接口芯片 ->cpu通过它们对部分外部设备进行访问;
3】其它芯片 ->用来储存相关的系统信息,或进行相关的输入输出处理;
这些芯片中都有一组可以由cpu读写的寄存器;
这些寄存器有两个特点:
1】都通过它们所在的芯片和cpu的总线相连;
2】cpu对它们进行读写时,都通过控制线,向它们所在的芯片发出端口读写命令;
cpu将这些寄存器都当做端口,对它们进行统一编址,从而建立了一个统一的端口地址空间;
每一个端口在地址空间都有一个地址;
1)端口的读写
端口地址通过总线来传送;
cpu最多可以定位64kb个端口,所以端口地址的范围为:0~65535;
对端口的读写指令只有两条:in和out;
不能用mov、push、pop等指令读写端口;
例如:从60h号端口中读入一个字节
in al,60h
该指令做如下操作:
1】cpu通过地址线,发出地址信息60h;
2】cpu通过控制线发出端口读命令,选中端口所在芯片,并通知将要从中读取数据;
3】端口所在芯片将60h端口中的数据通过数据线送入cpu;
注意:
in和out指令只能使用al或ax来存放从端口中读入的数据,或将要发送到端口中的数据;
访问8位端口时用al;
访问16位端口时用ax;
访问端口时,端口号必须保存在dx中或用立即数表示(例如61h);
例如:访问端口3f8h
mov dx,3f8h
in al,dx
往70h端口中写入数据,以及从71h端口中读取数据:
out 70h,al ;往70h端口写入数据
in al,71h ;从71h端口读入数据
2.shl和shr指令
shl和shr是逻辑位移指令;
shl是逻辑左移,功能:
1】将一个寄存器或内存单元中的数据左移
2】将最后移出的一位存放在标志位CF中
3】最低位补0
例如:
mov al,0100b
shl al,1
执行后,al的值为1000b;cf的值为0;
一个数x左移一位相当于该x=x*2;
比如:0010b=2,左移一位后结果为0100b=4;
注意:如果移动位数大于1,必须将移动位数放在寄存器cl中
mov cl,4
shr al,cl
shr是右移指令,和shl正好相反;
功能是:
1】将一个寄存器或内存单元中的数据右移
2】将最后移出的一位保存在CF中
3】最高位补0
3.关于CMOS RAM芯片
可以用cmos ram芯片来作为在程序中应用端口的例子;
1)关于cmos
pc中有一个cmos芯片,其功能与时间相关;
特征如下:
1】包含一个实时钟和一个128字节的ram储存器;
2】靠电池供电,因此关机后信息不会丢失;
3】128个字节中,0~0dh用来保存时间信息,其余部分内存保存系统配置信息供系统启动时bios读取;
4】该芯片有两个端口,70h和71h;
->70h为地址端口,存放要访问的coms单元的地址;
->71h为数据端口,存放用cmos中读取的数据或要写入cmos中的数据;
例如:读取cmos的2号单元中的数据需要下面两步
1】将2送入端口70h;
2】从端口71h中读出数据;
2)从cmos中读取时间
在cmos ram中,存放的时间信息长度都为一个字节;
其存放的单元分别为:
秒 ->0
分 ->2
时 ->4
日 ->7
月 ->8
年 ->9
比如想获取月份信息,就需要将8送入端口70h;
cmos中的时间信息以BCD码的方式存放;
BCD码是以4位2进制数表示十进制数;
例如:十进制数对应的BCD码
0 ->0000
1 ->0001
2 ->0010
8 ->1000
28 ->0010 1000
BCD码的值和十进制数的值是相等的;
想要在控制台中显示时间,需要将获取的时间码转换成其对应的ascii码;
数字转换成其对应的ascii码的公式为a=a+0x30;也就是加上十六进制的30;
代码:
assume cs:code
code segment
s1: db "2000/00/00 00:00:00","$"
s2: db 9,8,7,4,2,0
start: mov ax,cs
mov ds,ax
mov bx,offset s2
mov si,offset s1+2
mov cx,6
get:mov al,[bx]
out 70h,al ;往70h端口写入数据
in al,71h ;从71h端口读入数据
call set ;从cmos中读取时间,并设置到数据段中
inc bx
loop get
mov dx,offset s1 ;输出到控制台
mov ah,9
int 21h
mov ax,4c00h ;退出程序
int 21h
set:push bx
push cx
mov bh,al
mov cl,4
shr bh,cl ;设置十位
add bh,30h ;转为ascii
mov [si],bh
inc si
mov bl,al ;设置个位
and bl,00001111b
add bl,30h
mov [si],bl
add si,2
pop cx
pop bx
ret
code ends
end start
结果: