2011-05-17 43 views
2

功能在c如何理解微小c函數的彙編結果?

PHPAPI char *php_pcre_replace(char *regex, int regex_len, 
           char *subject, int subject_len, 
           zval *replace_val, int is_callable_replace, 
           int *result_len, int limit, int *replace_count TSRMLS_DC) 
{ 
    pcre_cache_entry *pce;    /* Compiled regular expression */ 

    /* Compile regex or get it from cache. */ 
    if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) { 
     return NULL; 
    } 

    return php_pcre_replace_impl(pce, subject, subject_len, replace_val, 
     is_callable_replace, result_len, limit, replace_count TSRMLS_CC); 
} 

其裝配:

php5ts!php_pcre_replace: 
1015db70 8b442408  mov  eax,dword ptr [esp+8] 
1015db74 8b4c2404  mov  ecx,dword ptr [esp+4] 
1015db78 56    push esi 
1015db79 8b74242c  mov  esi,dword ptr [esp+2Ch] 
1015db7d 56    push esi 
1015db7e 50    push eax 
1015db7f 51    push ecx 
1015db80 e8cbeaffff  call php5ts!pcre_get_compiled_regex_cache (1015c650) 
1015db85 83c40c   add  esp,0Ch 
1015db88 85c0   test eax,eax 
1015db8a 7502   jne  php5ts!php_pcre_replace+0x1e (1015db8e) 

php5ts!php_pcre_replace+0x1c: 
1015db8c 5e    pop  esi 
1015db8d c3    ret 

php5ts!php_pcre_replace+0x1e: 
1015db8e 8b542428  mov  edx,dword ptr [esp+28h] 
1015db92 8b4c2424  mov  ecx,dword ptr [esp+24h] 
1015db96 56    push esi 
1015db97 52    push edx 
1015db98 8b542428  mov  edx,dword ptr [esp+28h] 
1015db9c 51    push ecx 
1015db9d 8b4c2428  mov  ecx,dword ptr [esp+28h] 
1015dba1 52    push edx 
1015dba2 8b542428  mov  edx,dword ptr [esp+28h] 
1015dba6 51    push ecx 
1015dba7 8b4c2428  mov  ecx,dword ptr [esp+28h] 
1015dbab 52    push edx 
1015dbac 8b542428  mov  edx,dword ptr [esp+28h] 
1015dbb0 51    push ecx 
1015dbb1 52    push edx 
1015dbb2 50    push eax 
1015dbb3 e808000000  call php5ts!php_pcre_replace_impl (1015dbc0) 
1015dbb8 83c424   add  esp,24h 
1015dbbb 5e    pop  esi 
1015dbbc c3    ret 

正如我們可以看到,pcre_get_compiled_regex_cache需要參數,但爲什麼參數被壓入堆棧?

1015db7d 56    push esi 
1015db7e 50    push eax 
1015db7f 51    push ecx 
1015db80 e8cbeaffff  call php5ts!pcre_get_compiled_regex_cache (1015c650) 
+0

大概是因爲編譯器決定在寄存器中傳遞參數,或者因爲堆棧仍然包含所需的第一個參數。它不工作嗎? – sehe 2011-05-17 09:36:05

+1

它保存和恢復源索引,所以它似乎。 – Roman 2011-05-17 09:37:53

+2

TSRMLS_CC擴展到什麼程度?導致它看起來像第三個和最後一個參數的宏... – Necrolis 2011-05-17 09:41:25

回答

0

我猜TSRMLS_DCTSRMLS_CC宏包含一些隱藏的額外的參數。快速谷歌在PHP編程中將這些宏顯示爲全局狀態數據。有意義的是,函數聲明中的宏必須有一個參數,它的堆棧上的參數是[esp+02ch] - 第十個參數 - 您已經有9個參數,並且作爲堆棧中的第一個值傳遞(值從右向左推),接着是regex_len,然後是regex

+0

下面是宏的一個很好的解釋:http://blog.golemon.com/2006/06/what-heck-is-tsrmlscc-anyway.html – 2011-05-17 14:31:44