亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1652 | 回復(fù): 4
打印 上一主題 下一主題

[內(nèi)核入門] extern 一個(gè)函數(shù)指針 引發(fā)的問題 [復(fù)制鏈接]

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2015-04-30 09:31 |只看該作者 |倒序?yàn)g覽
本帖最后由 mrpre 于 2015-04-30 20:01 編輯

首先是這樣的,我在一個(gè)文件里面 定義了一個(gè)函數(shù)指針:
s32 (*test_func_ptr)(void * buf, s32 len, void * session) = dummy_func();


我需要在另外一個(gè)文件使用該函數(shù),第一次向下面一樣使用(死的稀里嘩啦的)
extern s32 test_func_ptr(void * buf, s32 len, void * session);
int test_func()
{
    void *ptr1, *ptr2;
    int a;
   
    test_func_ptr(ptr1, a, ptr2);
   
    return 0;
}

panic了。我看了一下匯編


0xffffffffc0380198 test_func:         daddiu    sp,sp,-16
0xffffffffc038019c test_func+0x4:     lui       v0,0xc045
0xffffffffc03801a0 test_func+0x8:     move      a0,zero
0xffffffffc03801a4 test_func+0xc:     move      a1,zero
0xffffffffc03801a8 test_func+0x10:    sd        ra,8(sp)
0xffffffffc03801ac test_func+0x14:    daddiu    v0,v0,30544
0xffffffffc03801b0 test_func+0x18:    jalr      v0                   //v0 是 test_func_ptr這個(gè)符號(hào)
0xffffffffc03801b4 test_func+0x1c:    move      a2,zero
0xffffffffc03801b8 test_func+0x20:    ld        ra,8(sp)
0xffffffffc03801bc test_func+0x24:    move      v0,zero
0xffffffffc03801c0 test_func+0x28:    jr        ra
0xffffffffc03801c4 test_func+0x2c:    daddiu    sp,sp,16

[0]kdb> 0xffffffffc0450000+30544
0xffffffffc0450000 = 0xffffffffc0457750 ([modlue_net] test_func_ptr)


然后我把 extern s32 test_func_ptr(void * buf, s32 len, void * session);
變換為 extern s32 (*test_func_ptr)(void * buf, s32 len, void * session);
這下總對(duì)了吧,果然,不再panic
但是問題來了,我查看了一下 test_func 對(duì)應(yīng)的匯編代碼。。。居然和上面的沒區(qū)別(基本沒區(qū)別)。
[0]kdb> id test_func
0xffffffffc037d040 test_func:         lui       v0,0xc045
0xffffffffc037d044 test_func+0x4:     daddiu    sp,sp,-16
0xffffffffc037d048 test_func+0x8:     move      a0,zero
0xffffffffc037d04c test_func+0xc:     move      a1,zero
0xffffffffc037d050 test_func+0x10:    ld        v0,30544(v0)
0xffffffffc037d054 test_func+0x14:    sd        ra,8(sp)
0xffffffffc037d058 test_func+0x18:    jalr      v0   //v0 還是 test_func_ptr這個(gè)符號(hào),我覺得應(yīng)該jalr dummy_func
0xffffffffc037d05c test_func+0x1c:    move      a2,zero
0xffffffffc037d060 test_func+0x20:    ld        ra,8(sp)
0xffffffffc037d064 test_func+0x24:    move      v0,zero
0xffffffffc037d068 test_func+0x28:    jr        ra
0xffffffffc037d06c test_func+0x2c:    daddiu    sp,sp,16


我對(duì)底層的東西不太平白,覺得如果和“編譯”沒關(guān)系的話,是不是和“鏈接”有關(guān)系?

望有大神釋疑。

論壇徽章:
1
拜羊年徽章
日期:2015-03-03 16:15:43
2 [報(bào)告]
發(fā)表于 2015-04-30 09:43 |只看該作者
本帖最后由 linuxfellow 于 2015-04-30 10:14 編輯

C語言的問題,與編譯器和底層無關(guān)。


論壇徽章:
20
程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-17 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-07-16 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-07-18 06:20:00每日論壇發(fā)貼之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16賽季CBA聯(lián)賽之江蘇
日期:2017-06-26 11:05:5615-16賽季CBA聯(lián)賽之上海
日期:2017-07-21 18:12:5015-16賽季CBA聯(lián)賽之青島
日期:2017-09-04 17:32:0515-16賽季CBA聯(lián)賽之吉林
日期:2018-03-26 10:02:16程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-07-15 06:20:0015-16賽季CBA聯(lián)賽之江蘇
日期:2016-07-07 18:37:512015亞冠之薩濟(jì)拖拉機(jī)
日期:2015-08-17 12:21:08
3 [報(bào)告]
發(fā)表于 2015-04-30 09:52 |只看該作者
這個(gè)區(qū)別很大吧。
x86下是兩種不同的call:

[~]$ cat a.c
extern  void f1(void);
extern  void (*f2)(void);

void f(void)
{
        f1();
        f2();
}
[~]$ objdump -d a.o

a.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <f>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   e8 00 00 00 00          callq  9 <f+0x9>   #直接尋址
   9:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # 10 <f+0x10>
  10:   ff d0                   callq  *%rax   #間接尋址
  12:   c9                      leaveq
  13:   c3                      retq  

論壇徽章:
13
程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-06-29 06:20:00每日論壇發(fā)貼之星
日期:2016-08-14 06:20:00操作系統(tǒng)版塊每日發(fā)帖之星
日期:2016-08-14 06:20:00每日論壇發(fā)貼之星
日期:2016-08-13 06:20:00數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2016-08-13 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-08-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-08-13 06:20:00每日論壇發(fā)貼之星
日期:2016-08-12 06:20:00數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2016-08-12 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-08-12 06:20:00操作系統(tǒng)版塊每日發(fā)帖之星
日期:2016-08-12 06:20:00綜合交流區(qū)版塊每日發(fā)帖之星
日期:2016-08-09 06:20:00
4 [報(bào)告]
發(fā)表于 2015-04-30 12:56 來自手機(jī) |只看該作者
本帖最后由 karma303 于 2015-04-30 12:59 編輯

  是編譯階段的問題。  
  你已經(jīng)在另一個(gè)模塊里,把test_func_ptr定義成函數(shù)指針。那么,“test_func_ptr”就是個(gè)普通的symbol,這個(gè)symbol本身的值不重要(假定是804a010),在804a010內(nèi)存處存放的只是一個(gè)4byte的數(shù)值,value是test_func這個(gè)函數(shù)的地址。
  再回到當(dāng)前的模塊。
  你欺騙編譯器說test_func_ptr只是個(gè)函數(shù),編譯器認(rèn)為,804a010內(nèi)存地址起,存放著一段函數(shù)代碼(instruction)。編譯器當(dāng)然直接跳過去:push eip; jmp (804a010-當(dāng)前eip)----------也就是call test_func_ptr.
  如果編譯器知道test_func_ptr只是一小塊兒函數(shù)指針,它會(huì)jmp dword [test_func_ptr],就是從test_func_ptr這兒取出真正的目標(biāo)函數(shù)地址,來調(diào)整eip。寫成mov eax,[test_func_ptr];jmp eax大同小異。

-----------------------
借一下3樓的代碼,用intel匯編看一下:
<a.c>
void f2(void){ }
void (*f1)(void) = f2;
<t.c>
extern void (*f1)(void);
extern void f2(void);
void main(void){
        f1();
        f2();
}

gcc -o t t.c a.c
objdump -d -Mintel ./t
080483b4 <main>:
80483b4:        55                           push   ebp
80483b5:        89 e5                        mov    ebp,esp
80483b7:        83 e4 f0                     and    esp,0xfffffff0
80483ba:        a1 10 a0 04 08               mov    eax,ds:0x804a010
80483bf:        ff d0                        call   eax
80483c1:        e8 02 00 00 00               call   80483c8 <f2>
80483c6:        c9                           leave  
80483c7:        c3                           ret  


------------PS:上面有些“jmp”該寫成“call”,我是覺得jmp清晰些。

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
5 [報(bào)告]
發(fā)表于 2015-04-30 20:07 |只看該作者
看大家的回復(fù),意思說 理論上確實(shí)兩段匯編代碼不一樣......我也理解大家說的指針和變量之間的關(guān)系,間接尋址和直接尋址之間的關(guān)系(一開始我沒看匯編,也這么理解,后來看了匯編我就郁悶了)?墒沁@的的確確發(fā)生了,兩個(gè)相似的匯編,一個(gè)跑起來了一個(gè)panic了……難道是mips的問題?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP