#include
int main()
執行這個程式,螢幕上會出現乙個 :)
很多人不懂其中的道理,在這裡我給大家分析下**。
先看這兩句:
const short int c1 = 49920;
const int c2 = 1073742008;
定義了兩個區域性變數,數值轉換成16進製為:
const short int c1 = 0xc300;
const int c2 = 0x400000b8;
其中變數c1的位址為:0x0012ff7c ,佔兩個位元組,c2的位址為:0x0012ff78,佔四個位元組。這兩個變數佔據了連續的空間。變數賦值後,從0x12ff78開始的記憶體單元儲存的位元組碼為:b8 00 00 40 00 c3 。對應的彙編碼是:
mov eax,400000h
ret
接下來的這句:
int (*pf)() = (int (*)())&c2;
分析如下:
定義了乙個函式指標,引數為null,返回值為int型別。 這個函式指標,指向上面的彙編碼。這樣,後面執行pf(),就執行了這段彙編碼。
繼續分析下面這句**:
printf("%c%c/n", *(char*)pf()-19, *((char*)pf()+1)-49);
先看*(char*)pf()-19這個表示式, 執行了了pf指向的彙編**,從彙編**看,
這個函式呼叫後的返回值是0x400000,pf()前面的char *是把函式的返回值轉換成乙個
char*型指標,這個指標指向0x400000,前面再加個*號,表示取0x400000位址的內容,
由於是char *型指標,因此從這個位址取乙個位元組。
*(char*)pf()-19 表示的是從0x400000取出的位元組內容再減去19。
接下來:*((char*)pf()+1)-49代表的意思是從0x400000 + 1的位址取出乙個位元組內容在減去49。
熟悉pe檔案結構的朋友一定知道,對於exe檔案0x400000是記憶體載入的基位址。
也就是說,0x400000 位元組的內容對應的是0x4d,0x400001 位元組的內容對應的是0x5a.
這是我們常說的pe檔案起始的兩個位元組,"mz"
這樣,表示式*(char*)pf()-19的結果是0x3a ,表示式*((char*)pf()+1)-49的結果是0x29
察看ascii碼表,輸出就是我們看到的樣子。
總結:
別看乙個這麼小的程式,但是其中涉及的知識面比較廣
比較有趣的C語言小程式
1.判斷是否是閏年 include int main void if a 1 printf d is a leap year n year else printf d not a leap year n year return0 2.判斷乙個日期是週幾,有兩種演算法 1 include stdio....
有趣的程式
include int main 執行這個程式,螢幕上會出現乙個 很多人不懂其中的道理,在這裡我給大家分析下 先看這兩句 const short int c1 49920 const int c2 1073742008 定義了兩個區域性變數,數值轉換成16進製為 const short int c1...
有趣的小演算法 1
乙個100大小的int陣列,要求隨機新增1 100的數到其中,且不能有重複。思考 在for 0 99 迴圈中 肯定要產生隨機數然後與陣列中元素比較,如果產生的隨機數在for 0 i 中有相等,則 跳出迴圈,再產生隨機數 如果不等,繼續在for 0 i 中比較,直到小迴圈中是i值還是不等,說明不存在相...