端口

在計算機結構中,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
結果:
   
相關文章
相關標籤/搜索