<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            C語言

            C語言竟是如何調用硬件

            時間:2025-01-20 05:37:26 C語言 我要投稿
            • 相關推薦

            C語言竟是如何調用硬件

              大家都知道我們可以使用C語言寫一段程序來控制硬件工作,但你知道其工作原理嗎?以下僅供參考!

              c語言在實際運行中,都是以匯編指令的方式運行的,由編譯器把C語言編譯成匯編指令,CPU直接執行匯編指令。

              所以這個問題就變成,匯編指令是如何操作硬件的?

              如果把硬件平臺限制在x86環境下,那么匯編指令操作硬件基本上只有兩種方式:

              方式一:

              通過向內存空間寫數據。硬件會把硬件上的各種寄存器(外行可以理解為訪問硬件的接口或者操作硬件的工具)映射到某一塊內存地址空間上,之后只要用匯編指令,甚至C語言去讀寫這一段內存地址空間(并非真正操作物理內存),就可以達到操作硬件的目的了。

              如果題主還有WindowsXP環境(虛擬機也可以),就可以用匯編指令直接操作顯存:

              MOV AX,B800

              MOV ES,AX

              XOR DI,DI

              MOV CX,0800

              MOV AX,5555

              REPZ STOSB

              硬件的各種寄存器會被映射到某一塊物理內存中,這種方式稱為MMIO,在Windows的設備管理器里,右鍵點設備,看屬性-》資源里,不少硬件設備都有“內存范圍”的參數,這里的內存范圍就表示這個硬件的資源可以通過訪問這一段內存來控制它。

              方式二:

              x86匯編中,還有兩個特殊的指令是IN和OUT,這是x86平臺上獨有的,上面圖里的I/O范圍,就是用IN/OUT這兩個指令來訪問和控制的。

              以上兩種訪問硬件的方式,第一種是可以用C語言實現的,上面一段匯編,本質上類似于C語言代碼:

              char ptr = 0xB8000;

              int i;

              for (i = 0; i 《0x800; i++)

              {ptr + i = 0x55;

              }

              第二種IN/OUT方式沒有直接的C語言語法對應,需要自己封裝匯編。

              那么為什么平時很難用C語言操作硬件呢?這是因為平時寫的代碼大多數都在保護模式下,保護模式下,直接訪問物理地址會受到限制,C語言操作的地址都是虛地址。

              對于Windows來說,要訪問物理地址,需要工作在內核模式,也就是的寫驅動才行。

              而在顯存方面,首先,題主要先明白物理地址和虛擬地址的概念。

              原來的8086cpu設計的時候,地址空間有一塊區域(640K-1M)之間,有一塊作為顯存使用

              這里你說的預留的地址,是指物理地址,這一段地址的準確范圍是000A0000-000BFFFF,不管是32位還是64位CPU,這一段物理內存地址一直都保留給顯存使用,不區分32位還是64位,也不區分保護模式還是實模式。

              可見這一段內存至今仍然是留給顯卡使用的。

              那么現在為什么不能直接用這段內存了?

              因為現在的軟件都運行在保護模式下,訪問的地址都是虛擬地址,而并非物理地址,包括你使用cmd命令打開的環境,都是虛擬地址,雖然32位XP里能用debug命令向000B8000上寫數據并能顯示在cmd的界面里,但本質上,這都是虛擬出來的。

              如果要想用這段顯存怎么辦?

              自己寫一個簡易的操作系統,不啟動顯卡的各種圖形加速功能,CPU進入保護模式后在GDT里映射一個4G的數據段,與物理地址一致,那么向000B8000上寫數據,就會像過去DOS一樣顯示在屏幕上,所以保護模式下也可以訪問這一段內存。所以,保護模式下,也可以用它。

              顯卡那么多顯存是怎么映射的?

              有很多內存地址被映射給顯存了,就是通過這種映射關系,把一些物理地址留給顯存,使得CPU能像訪問內存一樣訪問顯存資源。

              當然,實際情況是,2G顯存未必完全映射,而是只映射一部分地址,顯卡有一些開放的寄存器能夠控制哪部分顯存映射過來,這樣就能使得CPU在使用比較少的物理地址范圍的情況下,訪問全部的顯存。

              還有一個很有意思的事情:在虛擬機里,找到映射的高地址部分的第一塊內存區域,寫一個能直接訪問物理地址的程序(比如一個驅動),去讀這一塊內存,然后寫到文件里,再用屏幕截圖,也寫到文件里,會發現截圖的內容和顯存里讀出來的內容基本上是一樣的。

              網友awayisblue

              要回答你的問題,我們需要要知道:

              硬件是一種什么樣的存在

              什么是驅動。

              C語言怎么操作硬件

              我就不嚴格去定義這些概念了,我就以一個例子來通俗地講解一下吧。

              首先講硬件:

              先介紹一款單片機芯片STM8。

              這款芯片里面有cpu, 內存,寄存器(先不要覺得看到新名詞壓力大,繼續往下看)等等,相當于我們的電腦了,但還要外接其它硬件。

              這里你需要知道的概念是:

              芯片的引腳跟寄存器是相對應的,寄存器是8位的內存單元(對,存在于內存上面),當你往這個內存單元里面寫入數據時,芯片的引腳的電壓會發生變化,比如說我寫入的是01100001,則芯片上與之對應的8個引腳的電壓狀態(分為高電平與低電平兩種)會輸出:低高高低低低低高。

              cpu可以執行代碼指令,指令可以操作內存。

              結論:所以從上面兩點可以我們可以知道,cpu可以執行指令,使芯片的引腳電平(電壓)發生變化。

              關于這款顯示器,我們需要知道的是:

              它是有引腳的,這些引腳可以跟到前面介紹的那款單片機芯片的引腳相連。

              該顯示器有自帶的內存,用于存儲要顯示的字符,顯示器從該內存里面讀取字符來來顯示。

              單片機芯片與該顯示器相連后,可以通過引腳往該顯示器的內存里寫數據(通過多個引腳電平的高低不同來代表不同的數據,比如說:低高高低低低低高 代表01100001,這個數據寫在顯示器的內存里面,被顯示器所顯示,當然,會根據ASCII來顯示數字對應的字符,01100001對應的字符是‘a’),除了接收數據的引腳外,還有控制顯示器的引腳(這個我們會在驅動那里介紹,繼續往下看)。

              結論:單片機芯片與顯示器相連,可以通過引腳輸出的電平來控制顯示器的字符顯示。

              那么,綜合上面,也就是說,單片機芯片cpu可以通過執行指令來控制顯示器的字符顯示。

              而這里,題主所說的硬件,指的就是這個顯示器了。

              接下來講驅動:

              那么,什么是驅動呢?驅動無非就是硬件跟軟件的中間層,但我們不糾結這種關系,直接來看一下,對于我們這個例子,驅動指的是什么。首先我們要知道:

              顯示器支持很多種操作,比如說清除顯示,光標移動,讀取數據,寫數據等等。

              這些操作數據引腳和控制引腳來實現。

              引腳可以通過單片機芯片來控制。

              結論:我們可以通過在單片機芯片里面寫顯示器的“驅動”程序來屏蔽掉硬件(顯示器硬件)層。

              于是這里驅動程序,指的是顯示器所支持操作的程序表示。比如說清除顯示,我們可以編寫一個clear()函數,光標移動,我們編寫一個move_cursor()函數,讀取數據和寫數據分別為read()和write(),然后分別實現就可以了(通過向寄存器里寫數據的形式,進而控制引腳的電平變化,再而控制顯示器,這個過程前面已有介紹)。這些函數就是驅動程序了。為什么上面說驅動程序可以屏蔽掉硬件呢?因為程序員可以使用前面的驅動程序來直接操作顯示器(硬件),而不用知道太多關于硬件的事情,而一般的驅動程序也可以由廠家來提供。

              再說明一點:一般這些驅動程序可以用匯編寫(出于運行效率的考慮),也可以用C語言來編寫的,比如說我上面的例子,就可以直接用C語言來編寫。當然C語言內聯匯編的形式也可以。

              最后講C語言怎么操作硬件:

              相信到這里,C語言是怎么操作硬件的已經比較明白了。

              這里總結一下:

              C語言由CPU運行(實際上是先編譯成機器碼存在芯片里面然后執行),可以去操作內存。

              內存里有一段是跟寄存器相對應的,而寄存器是跟芯片的引腳相對應的,于是操作該段內存就能控制芯片引腳的電壓變化。

              硬件(比如說顯示器)有引腳(或者說排線,這些也是一樣的東西),這些引腳跟芯片的引腳相連可以接受芯片的控制。

              可以把對某個硬件的操作做成一系列操作函數,這些操作函數就是驅動程序了。

              于是我們的C語言只要去調用這個驅動程序就可以直接操作硬件了。(當然驅動程序也可以由C語言來編寫,所以C語言操作硬件并不一定要經過驅動程序)。

            【C語言竟是如何調用硬件】相關文章:

            C語言如何調用硬件02-14

            C語言是如何調用硬件的03-28

            c語言如何控制硬件05-24

            Java程序如何調用C/C++語言函數03-25

            如何在c語言中調用Linux腳本07-09

            C語言函數的運用及調用05-10

            C語言函數的遞歸調用05-17

            c語言調用系統命令06-13

            如何在C/C++中調用Java03-13

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院