2014-11-24 61 views
0

我正在研究由gcc生成的彙編代碼。 然而,我發現下面的代碼片段:

.LBE58: 
.loc 1 178 0 
cmpl $8224, %ebp 
jl .L12 
cmpl $8225, %ebp 
jle .L19 
leal -8240(%ebp), %eax 
cmpl $1, %eax 
ja .L12 
.LVL50: 
.LBB76: 
.LBB77: 
.loc 1 373 0 
movl 60(%esi), %eax 
.loc 1 374 0 
cmpl $8240, %ebp 
.loc 1 373 0 
movl 4(%eax), %ebx 

通過考察索裏的代碼,我發現,這應該是一個jmp指令。 爲什麼gcc編譯器使用3條指令而不是1條指令? 它是更有效的,或者是X86 CPU之間移植(我不知道任何x86處理器不支持JMP指令)

我的理由: JA的下一個指令是在.LBB77 MOV指令和這個mov指令對應於第373行的源。 如果ja不跳轉,那麼這是一個交叉函數執行。 這是一個非常奇怪的行爲,並不是預期的。 因此我認爲它必須是「jmp」。

最終結果 這不是一個JMP。它可以在源文件中運行第373行的指令。 已封閉。

============================的更多信息:

178     switch (s->state) 
179       { 
180     case SSL_ST_BEFORE: 
181     case SSL_ST_ACCEPT: 
182     case SSL_ST_BEFORE|SSL_ST_ACCEPT: 
183     case SSL_ST_OK|SSL_ST_ACCEPT: 

.................. 


342     default: 
343       SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE); 
344       ret= -1; 
345       goto end; 
346       /* BREAK; */ 
347       } 
348 
349     if ((cb != NULL) && (s->state != state)) 
350       { 
351       new_state=s->state; 
352       s->state=state; 
353       cb(s,SSL_CB_ACCEPT_LOOP,1); 
354       s->state=new_state; 
355       } 
356     } 
357 end: 
358   s->in_handshake--; 
359   if (cb != NULL) 
360     cb(s,SSL_CB_ACCEPT_EXIT,ret); 
361   return(ret); 
362   } 
363 
364 static int get_client_master_key(SSL *s) 
365   { 
366   int is_export,i,n,keya,ek; 
367   unsigned long len; 
368   unsigned char *p; 
369   const SSL_CIPHER *cp; 
370   const EVP_CIPHER *c; 
371   const EVP_MD *md; 
372 
373   p=(unsigned char *)s->init_buf->data; 
374   if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A) 
375     { 
376     i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num); 
377 
378     if (i < (10-s->init_num)) 
379       return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i)); 
380     s->init_num = 10; 
381 
+4

什麼是相應的源代碼?編譯器可能比你更知道如何編譯它;-) – EJP 2014-11-24 08:32:05

+3

_「通過調查soure代碼,我發現這應該是一個'jmp'指令。」_你能詳細說明你的調查嗎? – Michael 2014-11-24 08:32:27

+6

這3行形成了一個條件跳轉,你認爲編譯器應該生成一個無條件跳轉的原因是什麼? – nos 2014-11-24 08:34:25

回答

0

乍一看,此小片的代碼似乎是在抓取堆棧上某些東西的地址 - 一個局部變量的地址 - 將它放入一個寄存器中,看它是否大於1,並且只有在它跳過時才執行跳轉。

但我不明白爲什麼GCC會想地址比較字面1,因爲幾乎所有的地址大於1,在這種情況下jmp可能會很好的工作爲ja。所以也許它使用ebp寄存器來保存堆棧地址以外的內容?

無論如何,它不是一個簡單的跳躍。

+0

但是,這可以用作「JMP」指令。其中一個原因是編譯器確信它會一直跳躍。交換機聲明很難解決。 – bingosxs 2014-11-24 09:05:11

+0

你說得對。我沒有真正回答你的問題,這是爲什麼他們會使用與簡單跳躍相同的結果,但需要更多空間和時間。一種可能性是ebp中有一些東西不是一個普通的地址,而是一個偏移量,並且'lea'被用來做算術運算。在這種情況下,跳轉可能會失敗。 – Tony 2014-11-24 09:10:28

+0

是的。 ebp不是一個地址,而是一個普通的值。 \t有一條指令:''cmpl \t $ 8289,%ebp'' – bingosxs 2014-11-24 09:16:02

相關問題