C語言實現程式跳轉到絕對位址0x100000處執行

2022-02-13 09:22:37 字數 2915 閱讀 3666

嵌入式筆試題:想讓程式跳轉到絕對位址0x100000處執行,該如何做?

請詳細解釋一下所給的答案:

網上看到有如下答案:

*((void(*)(void))0x100000)();

經過在vc++6.0和linux gcc4.4.3下測試,均不能通過編譯。

vc++6.0報錯:error c2100: illegal indirection

gcc報錯:error: void value not ignored as it ought to be

應該是怎麼寫呢?

經過測試,有兩種方法:

答案1.    (*(void(*)(void))0x100000)();

答案2.    ((void(*)(void))0x100000)();

仔細觀察,第一種寫法只是第乙個*的位置不同,第二種寫法少了乙個*,但是都能正確編譯通過,且正確執行。

為什麼會有這兩種答案呢?查閱資料後發現,與歷史原因有關……

先來看看如下例子:

例一:

[cpp]view plain

copy

print

?#include 

void func(void)  

void main(void)  

執行程式後發現

兩次列印結果相同!!!

按照&運算子本來的意義,它要求其運算元是乙個物件,但函式名不是物件(函式是乙個物件),本來&func是非法的,但很久以前有些編譯器已經允許這樣做,c/c++標準的制定者出於物件的概念已經有所發展的緣故,也承認了&func的合法性。

因此,對於func和&func可以這樣理解,func是函式的首位址,它的型別是void (),&func表示乙個指向函式void func(void)這個物件的位址,它的型別是void (*)(),因此func和&func所代表的位址值是一樣的,但型別不一樣。func是乙個函式,&func表示式的值是乙個指標!

既然取不取址都可以,那麼*不*也都可以……

所以,在呼叫乙個函式的時候,也有兩種方法,正如前面的兩種答案。

例二:

[cpp]view plain

copy

print

?#include 

void func(void)  

void main()  

上面的兩種呼叫方法也都是正確的,編譯通過,正確執行。

其實,[cpp]view plain

copy

print

?func_p();  

也是正確的呼叫方式……

更有甚者

[cpp]view plain

copy

print

?(*func)();    

還是正確的……只是平時不這麼用罷了(注意此處是func,不是func_p)

暫且不考慮那麼多呼叫方式(知道就好了),現在回過頭來看看

[cpp]view plain

copy

print

?(*(void(*)(void))0x100000)();  

[cpp]view plain

copy

print

?((void(*)(void))0x100000)();  

到底是什麼東東……

1.首先來認識乙個新的資料型別,如:void (*)(void),和 int* 類似的乙個資料型別,只不過int*是乙個指向int型的指標,而void (*)(void)是乙個指向函式的指標,且這個函式無返回值,無引數。

2.然後給他外層加個括號,如:(void (*)(void)),這樣是不是很像(int*),我們在做強制型別轉換的時候需要在型別外加個括號的是吧。

3.接著把0x100000強制轉化為乙個函式指標,即:(void(*)(void))0x100000

4.最後就是呼叫這個函式,外層再加個括號,後面在加一對括號(參考例二的形式),

或者(*(void(*)(void))0x100000)();只是加不加*的問題。上面例二中可以看出,在用函式指標呼叫乙個函式時,加不加*都是可以的。

所以答案就出來了……

另外,你可能疑惑,按照例二中func_p(); 的形式,那麼(void(*)(void))0x100000();也應該對呀?

但是,實際測試,編譯報錯:error c2064: term does not evaluate to a function

為啥呢?我也不知道了……反正不管有沒有 * ,記得加個括號就好了……

那為什麼最開始的*((void(*)(void)0x100000))();不對呢?

因為沒見過*func();這麼用的……

如果要是外面再加一層括號就對了,如:(*( (void(*)(void)0x100000) )) ();

其實,把藍色括號去掉(藍色括號和綠色括號重複了),就又變成答案一了……

所以無論如何,最外層不能是*,必須是括號!

因為沒見過*func();這麼用的……

C語言實現程式跳轉到絕對位址0x100000處執行

網上看到有如下答案 void void 0x100000 經過在vc 6.0和linux gcc4.4.3下測試,均不能通過編譯。vc 6.0報錯 error c2100 illegal indirection gcc報錯 error void value not ignored as it oug...

C語言實現程式跳轉到絕對位址0x100000處執行

嵌入式筆試題 想讓程式跳轉到絕對位址0x100000處執行,該如何做?網上看到有如下答案 void void 0x100000 經過在vc 6.0和linux gcc4.4.3下測試,均不能通過編譯。vc 6.0報錯 error c2100 illegal indirection gcc報錯 err...

C語言實現程式跳轉到絕對位址0x100000處執行

嵌入式筆試題 想讓程式跳轉到絕對位址0x100000處執行,該如何做?請詳細解釋一下所給的答案 網上看到有如下答案 void void 0x100000 經過在vc 6.0和linux gcc4.4.3下測試,均不能通過編譯。vc 6.0報錯 error c2100 illegal indirect...