當前位置:首頁 > 技術學院 > 技術前線
[導讀]C語言在實際運行中,都是以匯編指令的方式運行的,由編譯器把C語言編譯成匯編指令,CPU直接執(zhí)行匯編指令。

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

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

先說代碼:

我們是用電腦的鍵盤來輸入的指令,每一個指令都對應一個ASCII碼,而這里的ASCII碼就是有序的電壓的高低(或電流的有無,下面只提電壓的高低),即我們輸入的是電壓的高低,你所看到代碼是這些電壓的高低控制顯示器所顯示的圖像,其實電腦也不知道它是什么,只知道這樣顯示。

結(jié)論:代碼其實就是存儲在存儲器(內(nèi)存、硬盤或者閃存等等)中有序的電壓的高低。

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

方式一:

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

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

MOVAX,B800MOV ES,AXXOR DI,DIMOV CX,0800MOV AX,5555REPZ STOSB

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

具體如下圖:


C語言是如何調(diào)用硬件?

方式二:

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

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

char ptr = 0xB8000;int i;for (i = 0; i 《0x800; i++){ptr + i = 0x55;}

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

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

對于Windows來說,要訪問物理地址,需要工作在內(nèi)核模式,也就是得寫驅(qū)動才行。

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

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

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

以下是我電腦上的截圖(系統(tǒng)環(huán)境為Win7 64位,CPU是i7 4770K):


C語言是如何調(diào)用硬件?

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

那么現(xiàn)在為什么不能直接用這段內(nèi)存了?

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

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

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

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

再看截圖:


C語言是如何調(diào)用硬件?

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

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

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

網(wǎng)友awayisblue

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

1、硬件是一種什么樣的存在

2、什么是驅(qū)動

3、C語言怎么操作硬件

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

首先講硬件:

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

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

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

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

cpu可以執(zhí)行代碼指令,指令可以操作內(nèi)存。

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

5、接下來我們再來看另一個硬件,液晶顯示器LCD1602(對,我就是這么迷你):

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

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

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

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

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

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

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

接下來講驅(qū)動:

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

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

這些操作數(shù)據(jù)引腳和控制引腳來實現(xiàn)。

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

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

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

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

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

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

這里總結(jié)一下:

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

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

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

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

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

網(wǎng)友北極

我們是用電腦的鍵盤來輸入的指令,每一個指令都對應一個ASCII碼,而這里的ASCII碼就是有序的電壓的高低(或電流的有無,下面只提電壓的高低),即我們輸入的是電壓的高低,你所看到代碼是這些電壓的高低控制顯示器所顯示的圖像,其實電腦也不知道它是什么,只知道這樣顯示。

結(jié)論:代碼其實就是存儲在存儲器(內(nèi)存、硬盤或者閃存等等)中有序的電壓的高低。

再說編譯:

編譯是一個有序的電壓的高低向另一種有序的電壓高低的一種轉(zhuǎn)換過程,下面以52單片機為例,我們編譯是從表示ASCII碼的那種有序電壓高低轉(zhuǎn)換為52單片機能夠識別的另一種規(guī)定好的有序電壓高低,即表示HEX文件的電壓高低。

結(jié)論:編譯出的結(jié)果還是電腦中存儲的有序電壓高低。

到單片機燒錄:

接下倆就是燒錄,理解了上面兩點就很容易理解下面的內(nèi)容,燒錄就是電腦中的有序電壓高低通過數(shù)據(jù)線傳輸?shù)絾纹瑱C中的ROM中。

接下來ROM就可以釋放其中的電壓來控制外圍的電路。

總結(jié):從代碼的編輯到最后對電路的控制都是電壓在起作用,只是為了方便我們而給我們展現(xiàn)的形式不一樣而已,而其本質(zhì)都是電壓,這樣也就不存在轉(zhuǎn)換。

理解這句話:世界上沒有軟件,軟件只是對硬件的一種反映,就像意識是對世界的一種反映是一樣的!

相信這樣就很容易理解了。

看到有人贊同了我的觀點,很開心,針對題目我再補充一點:

只要你提到0/1,提到軟件,這個問題就沒法理解。..因為軟件【包括0/1】和硬件始終存在一道無法跨越的鴻溝;

你說你在單片機中寫0,請問你是如何寫0的?在鍵盤上敲個0?實際還是電平【和我們理解的數(shù)字沒關系】,那個0只是你在電腦顯示器上電平的呈現(xiàn)形式,那個所謂的0【實質(zhì)是電平】可以傳輸?shù)絾纹瑱C中的ROM中,電平控制電平?jīng)]什么疑問吧,這樣就輸出低電平了。..

網(wǎng)友Chow Anod

北極已經(jīng)說的很到位了。我補充一些知識點:

1 語言層面上,C能直接操作的“硬件”只有內(nèi)存地址。雖然C支持register關鍵字,但是不能指定某個特定的寄存器,所以只有內(nèi)存地址。而C中操作內(nèi)存地址的方式就是指針。例如:

char p = 。..;p = 。..;

2 根據(jù)1反推,可以明白如果要開放給C來操作某個硬件,最直接的方案就是設計硬件的時候預先分配好一些固定的地址的用途,然后實際項目中往這些固定地址寫入合法的數(shù)據(jù)。這樣就可以通過類似

uint32_t p = SCREEN_ADDR;p = RGBA(0xff,0xff,0xff,0xff);

這樣的代碼來實現(xiàn)對硬件的操作了。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉