端口

在计算机结构中,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
结果:
   
 
 
 

转载于:https://www.cnblogs.com/ShiningArmor/p/11231705.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值