天天看點

寄存器編址

分析這幾個容易混淆的概念.

        引用一段資料: 幾乎每一種外設都是通過讀寫裝置上的寄存器來進行操作的。外設寄存器也稱為“i/o端口”,通常包括:控制寄存器、狀态寄存器和資料寄存器三大類,而且一個外設的寄存器通常被連續地編址。

cpu對外設io端口實體位址的編址方式有兩種:一種是i/o映射方式(i/o-mapped),另一種是記憶體映射方式(memory-mapped)。具體采用哪一種則取決于cpu的體系結構。

  有些體系結構的cpu(如powerpc、m68k等)通常隻實作一個實體位址空間(ram)。在這種情況下,外設i/o端口的實體位址就被映射到cpu的單一實體位址空間中,而成為記憶體的一部分。此時,cpu可以象通路一個記憶體單元那樣通路外設i/o端口,而不需要設立專門的外設i/o指令。這就是所謂的“記憶體映射方式”(memory-mapped)。主要缺點是是存儲器空間變小.

  而另外一些體系結構的cpu(如x86)則為外設專門實作了一個單獨地位址空間,稱為“i/o位址空間”或者“i/o端口空間”。這是一個與cpu的ram實體位址空間不同的位址空間,所有外設的i/o端口均在這一空間中進行編址。cpu通過設立專門的i/o指令(如x86的in和out指令)來通路這一空間中的位址單元(也即i/o端口)。這就是所謂的“i/o映射方式”(i/o-mapped)。與ram實體位址空間相比,i/o位址空間通常都比較小,如x86 cpu的i/o空間就隻有64kb(0-0xffff)。這是“i/o映射方式”的一個主要缺點。

         在張凡的<微機原理與接口技術>一書中提到的i/o端口的兩種編址方式:(1)i/o與存儲器統一編址(如單片機);(2)單獨編址(x86系統).這和上述的記憶體映射方式,i/o映射方式分别對應.

        我的了解是:寄存器就是i/o端口;而采用記憶體映射方式的i/o是存儲器的一個子集,采用i/o單獨映射方式的i/o是和存儲器平級的存儲空間.

     寄存器統一編址?

在wdm(windows driver model)中對裝置寄存器的通路,有些平台是同一編址的.通過直接通路記憶體的方式通路裝置寄存器.

請老大們解釋一下實作統一編址的詳細原理(象獨立編址分時輸出位址和資料方式等).

回複1  cpu架構決定了編址

一般一套總線的risc,把一段内部位址配置設定給内部寄存器。(一般是高端位址)。是以可以以看起來通路記憶體的方式來通路寄存器。而且,他所有位址不會重合,這麼就叫統一編址。

有2套總線結構的可以分開編址,操作同一位址借由不同指令,比如0位址可以是記憶體也可以是rom.由指令來分别。

回複2  wdm中兩種都支援

io位址空間的編址有兩種方式,io獨立編址和存儲器映像編址。

io獨立編址中,io端口操作有獨立的指令,如x86中的in,out,相應的io總線中有iord, iowr讀寫控制信号。

存儲器映像編址中用存儲器位址對io端口尋址,直接用操作存儲器的指令即可操作io,如mov,ld,st等等,51就是這種編址方式。

但是現在很多進階處理器對存儲器通路作了優化,如緩存,預取等等,而io操作通常要求實時性,比如一個寄存器目前的某個bit是1,必須在1ms後把它置成0,存儲器編址就得花另外的代價解決這個問題,這就是pci總線的記憶體空間分為prefecth和nonprefetch的原因。存儲器編址用c語言比較容易程式設計,比如要給0x80位址寫0x5a,隻需*((char*)(0x80)) = 0x5a即可,而在io獨立編址中,往往得寫一個函數或者是宏。

x86中有64k的io位址空間,外設接口卡可以使用,在pci總線中這是動态配置設定的,同時還可以使用記憶體空間,這在pci總線中也得到了很好的支援,在裝置枚舉時bios或者windows會動态的配置設定這些io空間和記憶體空間,一個外設到底使用什麼空間這是設計者考慮的事情。

但是對于wdm驅動程式來說,hal.dll導出了一系列的宏,隻要用這些宏操作就可以了,不過一般來說,自己寫驅動時,除了pci驅動,其他的很少使用到。