[英]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.