簡體   English   中英

帶GCC的函數指針,分配地址

[英]Function pointer with GCC, assigning an address

我遇到了一些我完全不明白的事情。 有一個函數原型:

typedef void ( * TMain ) ( void );

和一個函數變量:

TMain myFunc = MyFunc;
...
myFunc ();

當然,這很好用。 為什么不呢。

從MAP文件我知道“MyFunc”位於0x20100位置。 而現在有趣的事情。 在賦值“myFunc = MyFunc;”之后 變量“myFunc” 包含值0x20100而是0x20101!

我的問題是,我需要調用一個函數,我從表中知道地址。 所以我想我可以這樣做

myFunc = ( TMain ) myTable [ 5 ];    // that would be 0x20100
myFunc ();                           // which produces a proper crash

但是,如果我這樣做

myFunc = ( TMain ) ( ( Int8 * ) myTable [ 5 ] + 1 );  
myFunc ();

然后它工作。

這里發生了什么? 我是否總是要添加1的偏移量,或者這或多或少是偶然的? 或者有更好的(和工作)方式來完成任務?

非常感謝任何提示。 沃爾特

我的猜測是你在ARM目標上並且你已經在Thumb模式下構建了你的程序? (Thumb是ARM Ubuntu或Linaro的默認設置。)

函數地址的最低位告訴CPU應該在哪個指令集中解釋該函數。 0是ARM模式。 1是拇指模式。 因此,所有Thumb模式函數指針都將是奇數。

其他架構也以這種或那種方式使用這種習語。 通常只需將地址的底部兩位置零(使其為4字節對齊)並假設這是函數的真實位置是安全的。

多個CPU架構為特定目的保留函數的第一個字節。 VAXen在那里有一個保存寄存器掩碼。 CDC Cyber​​將回信地址放在那里。 有些人使用“地址”的一些位來表示地址間接(我不記得哪些,但它們來自20世紀70年代)。

除非你真的知道自己在做什么,否則你不應該編寫執行那種指針運算的代碼。 為變量分配函數名稱並使用它完成:保證可以在每個C實現上運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM