第十四章
CPU在操控各種存儲器時,都把它們當作內存來對待,把它們總地看做一個由若干存儲單元組成的邏輯存儲器,這個邏輯存儲器我們稱爲內存地址空間
PC機中,除了各種存儲器外,還有以下3種芯片和CPU通過總線相連
1、各種接口卡(網卡、顯卡)上的接口芯片,它們控制接口卡進行工作
2、主板上的接口芯片,CPU通過它們對部分外設進行訪問
3、其他芯片,用來存儲相關的系統信息,或進行相關的輸入輸出處理
這些芯片中都有一組可以由CPU讀寫的寄存器,它們在物理上處於不同芯片上,但有兩個共同點
1、都和CPU的總線相連(通過它們所在的芯片進行)
2、CPU對它們進行讀或寫的時候通過控制線向它們所在的芯片發出端口讀寫命令
從CPU角度,將這些寄存器都當作端口,對它們進行統一編址,建立一個統一的端口地址空間,每一個端口在地址空間中都有一個地址
至此,CPU可以直接讀寫以下3個地方的數據
1、CPU內部的寄存器
2、內存單元
3、端口
14.1 端口的讀寫
CPU通過端口地址定位端口進行訪問,,因爲端口所在的芯片和CPU通過總線相連,所以,端口地址和內存地址一樣,通過地址總線來傳送,CPU最多可以定位64KB個不同的端口,端口地址爲0~65535
端口的讀寫指令只有兩條:in和out,分別從端口讀取/寫入數據
比較CPU執行內存訪問指令和端口訪問指令時候,總線上的信息
訪問內存:moc ax,ds:[8]
執行時總線相關的操作如下
1、CPU通過地址線將地址信息8發出
2、CPU通過控制線發出內存讀命令,選中存儲芯片,並通知它將要從中讀取數據
3、存儲器將8號單元中的數據通過數據線送入CPU
訪問端口:in al,60h ; 從60端口所在芯片讀入一個字節
執行時總線相關的操作如下
1、CPU通過地址線將地址信息60h發出
2、CPU通過控制線發出端口讀命令,選中端口所在芯片,並通知它將要從中讀取數據
3、端口所在芯片將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
in al,dx ; 從3f8h端口讀入一個字節
out dx,al
14.2 CMOS RAM芯片
PC機中有一個CMOS RAM芯片,簡稱CMOS,其有如下特徵
1、包含一個實時鐘和128個存儲單元的RAM存儲器
2、該芯片靠電池供電,關機後內部的實時鐘仍可正常工作,RAM中的信息頁不會丟失
3、128個字節中,內部時鐘佔0~0dh單元來保存時間,其餘大部分單元保存系統配置信息,供啓動時BIOS程序讀取,BIOS也提供相關程序使得在開機時能夠配置CMOS中的系統信息
4、芯片內部有兩個端口,地址爲70h和71h,CPU通過這兩個端口進行讀寫CMOS RAM
5、70h爲地址端口,存放要訪問的CMOS RAM單元的地址,71h爲數據端口,存放從選定的CMOS RAM單元讀取或要寫入其中的數據
總結,CPU對CMOS RAM的讀寫分爲兩步進行,如讀CMOS RAM的2號單元
將2送入端口70h,從71h讀出2號單元的內容
mov al,2
out 70h,al
in al,71h
14.3 shl和shr指令
shl和shr是邏輯位移指令
shl是邏輯左移指令
功能:將一個寄存器或內存單元中的數據向左移位,將最後移出的一位寫入CF,最低位補零
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
將X邏輯左移一位,相當於X=X*2(會有溢出)
shr是邏輯右移
功能:將一個寄存器或內存單元中的數據向右移位,將最後移出的一位寫入CF,最高位補零
如果移動位數大於1,移動位數放在cl中
將X邏輯左移一位,相當於X=X/2(會有溢出)
編程,用加法和移位指令計算(ax)=(ax)*10
mov bx,ax
shl ax,1
mov cl,3
shl bx,cl
add ax,bx ;(ax)=(ax)*2+(ax)*8
14.4 CMOS RAM中存儲的時間信息
CMOS RAM中,存放着當前的時間:年、月、日、時、分、秒,它們的長度都爲一個字節
存放單元:秒:0
分:2
時:4
日:7
月:8
年:9
這些數據以BCD碼的方式存放
BCD碼是以4位二進制數表示十進制數的編碼方法
如26用BCD碼錶示:0010 0110
可見一個字節可表示兩個BCD碼,在CMOS RAM存儲時間信息的單元中,存儲了用兩個BCD碼錶示的兩位十進制數,高4位的BCD碼錶示十位,低4位表示個位
如 00010100b表示14
編程,在屏幕中間顯示當前的月份
assume cs:code
code segment
start: mov al,8
out 70h,al ; 存儲在CMOS RAM的8號單元
in al,71h ; 從數據端口取得指定單元中的數據
mov ah,al
mov cl,4
shr ah,cl ; ah中爲十位的數碼值(8位的高4位爲0)
and al,00001111b ; al中爲個位的數碼值(8位的高4位爲0)
add ah,30h ; BCD碼+30h=十進制數對應的ASCII碼
add al,30h
; CMOS中一個字節可以表示一個月份,但由於可能存在兩位數
; 所以個位十位分別存在兩個寄存器中
; 這樣方便轉換爲ASCII碼,作爲字符進行顯示12 = '1' '2'
mov bx,0b800h
mov es,bx
mov byte ptr es:[160*12+40*2],ah ; 十位
mov byte ptr es:[160*12+40*2+2],al
mov ax,4c00h
int 21h
code ends
end start
實驗十四
編程,以年/月/日 時:分:秒 的格式,顯示當前的日期、時間
assume cs:code,ds:data
data segment
db 'yy/mm/dd hh:mm:ss'
db 9,8,7,4,2,0
data ends
code segment
start: mov ax,data
mov ds,ax
mov si,0
mov di,17 ; CMOS中偏移地址的索引
mov cx,6
s: push cx
mov al,[di]
out 70h,al
in al,71h ; 從71h端口獲取數據
mov ah,al
mov cl,4
shr ah,cl ; ah保存十位上的數字
and al,00001111b ; al保存個位上的數字
add al,30h ; 得到對應字符的ASCII碼
add ah,30h
mov [si],ah ; 保存到data段中
mov [si+1],al
add si,3 ; 指向下一個要填入數據的地址
add di,1
pop cx
loop s
mov ax,data
mov ds,ax
mov si,0
mov cx,17
mov ax,0b800h
mov es,ax
mov di,160*13+32*2
s1: mov al,[si]
mov es:[di],al
mov al,02h ; 顏色屬性
mov es:[di+1],al
inc si
add di,2
loop s1
mov ax,4c00h
int 21h
code ends
end start