8086汇编--端口
端口
在PC机中通过总线与CPU相连的芯片,除了各种储存器外,还有以下三种芯片:
- 各种接口卡上的接口芯片
- 主板上的接口芯片,主板通过它们对部分外设进行访问
- 其他芯片,用来提供相关的系统信息,或进行相关的输入输出处理
在这些芯片中,都有一组可以由CPU读写的寄存器,它们都通过自己所在的芯片与CPU的总线所连接。CPU这些寄存器进行读写的时候,都是通过控制线,向这些芯片的端口发出读写命令。
所以,从CPU的角度看,这些CPU都被当成端口,并且就像逻辑地址一样,CPU对这些端口进行统一编址,从而建立一个统一端口地址空间,每个端口在里面都有一个对应的地址。
CPU可以在 CPU内的寄存器、内存单元、端口这三个地方直接读写数据。
端口的读写
在PC系统中,CPU最多定位64KB个端口,端口地址也是通过地址总线来传输的,所以,端口地址的范围为0~65535
我们以前向内存读写数据的过程一般都是:CPU先通过地址总线把要进行读写(假如为读)的数据的内存单元地址传送到内存,然后通过控制总线向内存发出读的命令,然后那个内存中的数据再通过控制总线传输到CPU中。
而我们现在对端口的读写,我们只能把端口中的数据在AX或AL之间来进行读写,8位的端口数据就用AL,16位的就用AX。并且我们只有两条指令 : in 和 out 。分别对应着读和写。比如:要向200h端口读数据到AL中 in al,200h
执行这个指令的过程:CPU通过地址总线将地址 200H 发出,CPU通过控制总线,选定端口所在芯片,向其发出读取命令,通知它要从中读取数据,端口所在芯片通过数据总线将端口200h中的数据传送到CPU。
我们也可以将端口号放在寄存器DX中。 in al,dx , out dx,al
CMOS RAM 芯片
PC机中有一个叫 CMOS RAM 的芯片,简称 CMOS芯片,它有以下几个特征:
- 它有一个实时钟和一个包含128个存储单元的RAM存储器。
- 这个芯片靠电池供电,所以断电后还能工作,其RAM中的信息不会丢失,实时钟仍然可以正常工作。
- 在这个芯片的有128个存储单元的RAM存储器中,只有 0~0d 的单元是用来存储时间信息的,其他单元都是用来保存系统配置信息的,所以我们的BIOS也会提供相关的程序,使得开机时得以配置CMOS RAM 中的系统信息
- 该芯片内部有两个端口,它们的端口地址分别为 70h 和 71h 。70h的端口是地址端口,存放要访问的CMOS RAM的单元的地址。71h的端口是数据端口,存放在CMOS RAM单元中选定的数据。
所以,假如我们要从CMOS RAM中读取单元2中的数据,过程应该是这样的:将 2 送入 70h ,从 71h 中读出2号单元的内容。
shl和shr命令
shl为左移命令,它的功能就是将一个寄存器或者一个内存单元中的数据左移,假如左移一位,那么移出的那一位会被放在CF中,就是那个进位借位的标志位。然后空出来的那一位用0填充。比如 mov al,10110010b shl al,1 。这个表示将AL中的数据左移一位,执行左移指令后,AL中的数据就变成了 01100100,CF中的数据就变成了1。假如问我们移动的位数超过1位,那么我们就必须将移动位数放在CL中,而存入CF中的也会是最后一位移出来的数据。比如 mov al,10110010b mov cl,3 shl al,cl 这个指令就是将AL中的数据左移三位,左移后AL中的数据将会变成10010000b,CF中的数据为1.
而 shr 就是右移指令,道理和左移指令是一样的,只不过它是往右移。
CMOS RAM中存储的时间信息
在 CMOS RAM中存放了 年、月、日、时、分、秒这几个时间信息,这六个信息的长度都为一个字节,对应的存放单元为:
秒:0,分:2,时:4,日:7,月:8,年:9
而这些数据都以BCD码的形式存放,下面介绍一下BCD码
BCD码就是用4位二进制数来表示十进制数的码。我们来看一个例子就一目了然
比如说数值23用BCD码来表示就是 : 0010 0011,要4位4位地看,直接就是拿4位二进制数表示的十进制数堆砌在一起就可以了。假如有一个字节的BCD码,那么高位的就表示十位,低位的表示个位。
我们编写一个显示当前月份的程序:
我们先想端口70h传送端口号8,里面存放了月份的数据,然后我们再从端口71h中读取月份的数据存储在AL中(因为它是一个字节的数据),然后因为这些时间数据是用BCD码来存放的,所以我们要通过一些转换来使其变成十进制数对应的ASCII码。我们直接拿每一个BCD码加上30h就可以了,因为BSD码是4位的,而我们的月份的数据是一个字节,也就是两个BCD码,所以我们要将它们分开来算,所以先将al中的值复制到AH中,然后将AH中的值往右移4位,这样AH中存放的就是原来数据的高4位了,然后因为AL中只能留着原来的底4位,而此时AL中的低4位还是原来数据的低4位,所以我们用 and 指令来使AL中高4位的值都变为0,而低四位不变。最后我们再将AH,AL中的数据放入显存中。
最后我们在debug中追踪程序