這裡說的函式主要指的是inline函式、static函式。inline函式比較特殊,它既具有巨集的性質,同時也能讓編譯器對它進行函式檢查。static函式同樣也比較特殊,它只可以被同檔案的函式使用。如果static函式在include檔案中,那麼這個標頭檔案只要被使用一次,那麼這個函式就要在exec檔案中重新出現一次。現在大家可能理解起來有點困難,但是請大家稍微等待一下,下面我們將會用示例進行說明。最後,我們用乙個替換的技巧對函式指標進行修改,讓你呼叫的函式發生修改,這樣給大家都函式的定義加深一下印象。
(1)內聯函式
[cpp]view plain
copy
inline
intadd(
inta,
intb)
那麼這個函式在應用的時候,會怎麼編譯呢,可以看一下?
[cpp]view plain
copy
0040114a mov eax,1
0040114f add eax,2
00401152 mov dword ptr [ebp-4],eax
inline函式是一種特殊的函式。在進行函式編譯的時候,編譯器會對內聯函式這段**按照函式的要求進行格式檢查。但是編譯生成執行**的過程中,編譯器會把這段**按照巨集的性質複製到call的函式當中。所以在call函式中,我們發現這段呼叫**並不是call的形式,而是直接按照語句的形式。但是這種inline函式中的**行數不能過多,因為我們內聯的目的就是就是減少call的機會。
注意:a) 函式在編譯的時候需要開啟inline優化開關,【project】->【setting】->【c/c++】->【optimizations】,在內聯擴充套件中選擇第二項
b)編譯的時候會生成錯誤,那麼刪除編譯指令/zi即可,結果是原始碼無法單步除錯,只能彙編級單步除錯
(2) static函式是什麼屬性
[cpp]view plain
copy
static
intadd(
inta,
intb)
a) 如果在不同的原始檔都有這樣乙個add函式呢 ?
如果在不同的檔案裡面函式宣告為static函式,那麼沒有關係,各個static函式只為各個檔案使用,不存在multi definition的問題。
b)如果標頭檔案有這樣乙個static函式宣告和定義?
標頭檔案中有乙個static函式的話,那麼呼叫這個函式的每個檔案都為這個static函式重新編譯一下。結果和a)的結果是一樣的,大家可以自己試試看一下,對static函式位址列印一下,看看是不是add函式的位址是一樣的。
(3)乙個修改函式位址的範例
[cpp]view plain
copy
#include
intadd(
inta,
intb)
intsub(
inta,
intb)
void
set()
} void
process()
簡單介紹一下,上面的**包括四個函式,add函式和sub函式主要為了替換測試使用,set函式是修改**段訪問屬性的一段**,而process函式就是我們測試使用的一段**。其實這段**的意思不難,目的在於你在call add函式,發現實際上在call的是sub函式。那麼我們是怎麼做到的呢,關鍵在兩個方面:(1)修改add 函式**段的訪問屬性;(2)修改add函式第乙個位元組的內容,那麼我們需要把函式add處地內容修改為jmp sub,那麼就要先修改屬性,後修改內容。
用彙編的眼光看C (之特殊函式)
這裡說的函式主要指的是inline函式 static函式。inline函式比較特殊,它既具有巨集的性質,同時也能讓編譯器對它進行函式檢查。static函式同樣也比較特殊,它只可以被同檔案的函式使用。如果static函式在include檔案中,那麼這個標頭檔案只要被使用一次,那麼這個函式就要在exec...
用彙編的眼光看C (之特殊函式)
1 內聯函式 view plain inline intadd inta,intb 那麼這個函式在應用的時候,會怎麼編譯呢,可以看一下?view plain 0040114a mov eax,1 0040114f add eax,2 00401152 mov dword ptr ebp 4 eax ...
用彙編的眼光看C (之特殊函式)
1 內聯函式 inline int add int a,int b 那麼這個函式在應用的時候,會怎麼編譯呢,可以看一下?0040114a mov eax,1 0040114f add eax,2 00401152 mov dword ptr ebp 4 eax inline函式是一種特殊的函式。在進...