更新時間:2024-12-22 16:59:59作者:佚名
1、嘮叨(聽聽文章配上音樂效果更好)
今天文章一開始,我就為大家挑選一首非常經(jīng)典的歌曲。喜歡《仙劍》的朋友聽到這首音樂,腦海中可能會閃現(xiàn)出另外一個場景。你可以感覺到!今天我就一步步講解C語言關鍵字寄存器。可能你在日常的項目開發(fā)中不太會用到這個關鍵字。他們中的大多數(shù)人都是從書籍和文獻中知道的。估計有的朋友根本沒有打過這個關鍵字。關鍵詞。哈哈,作者在之前的文章中一直提到“存在即合理”的觀點。這也是讓我在生活和學習中始終充滿好奇心的指導思想。好了,廢話不多說,進入今天的正題。筆者將通過實驗現(xiàn)象來幫助大家理解和分析這個關鍵詞:
2. 注冊基本介紹
注冊字面意思是注冊。 C語言中用this關鍵字修飾表示該變量被頻繁使用,如局部變量定義:register int Var = 0;,建議將變量放在寄存器中進行操作。以提高速度。 CPU在運行時需要從外界讀取數(shù)據(jù)。數(shù)據(jù)來源主要來自: 1)寄存器; 2)現(xiàn)金; 3)記憶。然而CPU訪問內(nèi)存時,大部分數(shù)據(jù)都要經(jīng)過寄存器。但這種方式與直接訪問寄存器相比,增加了數(shù)據(jù)訪問的時間。在我們上一篇文章中,我們說過局部變量存在于棧中,棧存在于內(nèi)存中。如果我們可以將變量放入寄存器中,不是可以加快訪問速度嗎?
但使用register關鍵字時需要注意以下幾點:
1)我們都知道&符號的意思是獲取內(nèi)存地址,所以由于是用寄存器修改的,所以一般不能使用該符號進行訪問。
2)前面我們提到了C語言中各種數(shù)據(jù)的存儲方式。例如,全局變量或靜態(tài)變量在內(nèi)存中具有特定的地址。那么可以用register修改嗎?肯定不能修改,那么什么變量可以用this關鍵字修改呢?答案是局部變量。在上一篇文章中我也提到過,局部變量在函數(shù)運行過程中會自動分配在棧上,而棧也在內(nèi)存中。為什么可以分配到寄存器中呢? (哈哈,這三個問題讓我很困惑!)
如上圖所示,局部變量的生命周期很短,寄存器不會一直被占用。不過,函數(shù)1使用完之后,就可以被函數(shù)2使用了,這樣就大大提高了運行速度。
3)我們都知道芯片內(nèi)部的寄存器是有限的,并且每個寄存器都有特定的功能。我們可以用來存儲變量的并不多,更何況并不是所有類型的變量都可以存儲在寄存器中。使用,這個需要根據(jù)具體的芯片來確定,比如浮點數(shù)在大多數(shù)芯片中是不能放在寄存器中進行讀寫的,所以寄存器只是告訴編譯器該變量會被頻繁使用。建議放在寄存器中進行讀寫。至于是否存儲,編譯器必須自己決定,所以有時編譯會忽略這個關鍵字。
好吧,有一些注意事項可能需要用例子來解釋。光在這里談論它們是沒有用的。讓我們做一些實驗。
3.實驗現(xiàn)象看套準效果
我寫了一個簡單的測試程序,就是我們學習編程最先用到的循環(huán)延遲。我們通過register關鍵字修改和不修改局部變量來獲取程序運行時間。 (使用Dev_C++運行程序)
#include <stdio.h>
#include <stdlib.h>
/*************************************
* Fuction: 測試register
* Author : (公眾號:最后一個bug)
************************************/
int main(int argc, char *argv[]) {
//register long cnt = 0;
long cnt = 0;
int timer = 0;
for(cnt = 0;cnt < 100000000;cnt++)
{
timer++;
}
printf("歡迎關注公眾號:最后一個bug!");
return 0;
}
不修改寄存器的情況下register是什么意思?怎么讀網(wǎng)校頭條,大約運行3次的時間:
使用寄存器修改三倍的大概運行時間:
簡單分析一下:以上結果僅供對比(筆者運行程序所用的電腦仍然是大學時使用的電腦,雖然更換了固態(tài)和內(nèi)存模塊,但畢竟還是古董)。可見,使用寄存器確實可以縮短程序執(zhí)行時間。到時候有些朋友就會問了。前面說過,register只建議放在一個用于讀寫的寄存器中。那么如何判斷程序是否已經(jīng)放入寄存器來運行程序呢?答案就是三個字------“看程序的匯編”! !
4.如何在Dev_C++中查看C程序的匯編
這里簡單介紹一下Dev_C++的程序集查看功能,主要是為后面的知識講解做鋪墊。同時,最近我發(fā)現(xiàn)很多朋友還在使用VC++學習,也遇到了很多安裝和系統(tǒng)兼容性問題。筆者覺得如果只是為了學習,可以安裝Dev_C++軟件進行練習。同時,安裝包較小,安裝過程也非常方便。
Dev_C++的基礎教程可以在網(wǎng)上搜索學習。這里筆者簡單講一下如何調(diào)試和查看代碼匯編?為了方便大家驗證結果。
1)在代碼行號前面放置一個端點,然后點擊左下角的“調(diào)試”,進入調(diào)試狀態(tài)。
2) 進入調(diào)試模式,調(diào)試選項卡中的所有按鈕均被激活。點擊ViewCPUwindows,彈出對應的匯編語言窗口。同時,單擊“下一條指令”,執(zhí)行一條匯編指令。其他按鈕的功能和我們的大致相同。正常的調(diào)試功能類似。大家可以去網(wǎng)上搜索了解一下,這里不再贅述。
5、判斷注冊是否有效?
上面已經(jīng)鋪好了。要判斷寄存器是否有效,只需檢查相應的匯編代碼即可。如果我們從寄存器中讀寫被寄存器修改的變量,就說明編譯器已經(jīng)對其進行了優(yōu)化。如果仍然是來自相應的內(nèi)存值,編譯器不會優(yōu)化。我們簡單看一下修改和不修改的結果。
1) 使用寄存器修改的匯編語句:
分析:我們看到C語言中的cnt++在右邊的匯編中變成了add ebx,0x1;這說明cnt確實是放入寄存器中使用的。
2)不修改寄存器的匯編語句:
分析一下:我們可以看到,這里的cnt++取的是esp+0x1c地址所在內(nèi)存的值,進行自增操作,這樣我們最終就得到了上面的程序運行時間,顯然是慢了一些。
這里補充一些知識:正在學習ARM的朋友應該知道,ARM中傳遞的函數(shù)參數(shù)大部分都是通過r0~r1寄存器來操作的,更多的其他參數(shù)是通過棧傳遞的,所以我們有時通過盡量不要輸入更多超過4個參數(shù),這樣就可以在寄存器中完成更多的處理,提高程序的效率。我在這里簡單提一下。我會發(fā)表一篇關于如何提高程序效率的文章供大家閱讀。
6. 最后總結
你應該感覺寄存器本身其實很簡單。根本沒什么可說的。但由于它有一定的模糊性,所以會有人確認。不過,在確認的過程中,你其實學到的不僅僅是這個關鍵字register是什么意思?怎么讀,還有很多額外的知識,比如程序的運行、編譯處理器的處理等等,知識都是相互關聯(lián)的,所以筆者經(jīng)常檢查他的自己的知識體系,尋找并填補空白。然而,現(xiàn)代編譯器往往不使用register關鍵字,編譯器會根據(jù)代碼自動優(yōu)化。處理,但是如果你想按照自己的想法來優(yōu)化程序,你還是需要了解清楚。