2013-07-04 120 views
2

我討厭這樣的語法問題,但我一直沒能通過搜索找到答案。我不確定每個變量聲明的含義。我對第三種猜測的最佳猜測是,它將邏輯和標籤檢查點的地址以及頁面大小的倒數作爲無符號長整型,然後將其重新命名爲void指針。代碼是從這裏:http://nmav.gnutls.org/2011/12/self-modifying-code-using-gcc.html無法弄清楚這個c語法是什麼

int (*my_printf) (const char *format, ...); 
void (*my_exit) (int); 
void *page = 
    (void *) ((unsigned long) (&&checkpoint) & 
    ~(getpagesize() - 1)); 

謝謝!

+1

前兩個是函數指針 – FDinoff

+0

是的,這正是它所做的。不知道爲什麼你需要問這個。你所做的只是用言語表達這個表達。 –

+2

請注意,「標籤地址」('&& checkpoint',here)是一個GNU C擴展,並且可能無法在其他編譯器中使用。 – torek

回答

0

前兩個函數指針分別與printfexit兼容。例如。你可以這樣做:

my_exit = exit; 
my_exit(3); 

它就相當於叫exit(3)

你對第三點的猜測是正確的。這取決於頁面大小始終是2的冪的事實。因此,pagesize-1將具有二進制模式,其全部位於低位,全0位於高位。反轉它反轉這些位。這可以用作帶地址的位掩碼,以返回地址指向的頁面開始的地址。然後它將page設置爲包含checkpoint的頁面的開頭。

+0

非常感謝。爲什麼他們使頁面無效*雖然,而不是將其作爲無符號長整型?另外,爲什麼該位掩碼工作返回頁面的開始?比如說,頁面大小是8,檢查點地址是00100000. pagesize-1的倒數是1111000。&將是00100000.爲什麼這一定是包含檢查點的頁面的開始?例如,它是否也可以從00011111開始,並且在包含檢查點的情況下仍然保持8的頁面大小? – user2142343

0

int (*my_printf) (const char *format, ...);聲明一個函數指針,該指針返回一個int值,並將c樣式字符串作爲第一個參數,並在format參數之後具有可變數量的參數。

void (*my_exit) (int);聲明一個函數指針,它不返回任何東西,但是接受一個int。

void *page = (void *) ((unsigned long) (&&checkpoint) & ~(getpagesize() - 1));聲明瞭一個通用指針,該指針相當於指向checkpoint的指針的地址,頁面大小減1。

5

my_printf是一個返回int的函數的指針,它接受一個char指針參數和其他變量列表。

my_exit是一個無返回值的函數指針,取一個int參數。

page是指向某種未指定類型的指針。它被分配了一個不應編譯的表達式的值,因爲&&是一個二元操作符,並且沒有左操作數,並且一元地址的地址是沒有意義的。 & ~(getpagesize() - 1)位掩蓋了可能被認爲是地址的低位,然後該地址將指向頁面的開始。

一元&&是一個GNU C擴展,它接受一個(goto)標籤的地址,所以這個構造基本上得到了包含該標籤的代碼頁的起始地址。這是編譯器和操作系統特定的東西,而不是真正的C語言的一部分。