2014-11-24 2 views
0

gcc에서 생성 한 어셈블리 코드를 연구 중입니다. 그러나, 나는 다음과 같은 코드 조각을 발견하십시오 soure 코드를 조사하여

.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 컴파일러가 1 명령 대신 3 명령을 사용하는 이유는 무엇입니까? JA의 다음 명령은 .LBB77에서 MOV 명령이고 :

MY 이유는 (필자는 JMP 명령어를 지원하지 않는 임의의 x86 CPU를 모르는) 는 더 효율적인 또는 그것은 X86 CPU를 사이에 이식 이 mov 명령은 373 행의 소스에 해당합니다. ja가 점프하지 않으면이 함수가 교차 실행됩니다. 이것은 매우 이상한 행동이며 예상하지 못합니다. 따라서 "jmp"여야한다고 결론을 내 렸습니다.

최종 결과 : 이것은 JMP 아닙니다. 소스에서 373 행의 명령을 실행할 수 있습니다. CLOSED.

============================ 추가 정보 : 언뜻

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

+3

_ "soure 코드를 조사하면 이것이 jmp 명령어 여야합니다. _ _ 조사를 좀 더 자세히 설명해 주시겠습니까? – Michael

+6

이 세 줄은 조건부 점프를 형성합니다. 컴파일러가 무조건 점프를 생성해야한다고 생각하는 이유는 무엇입니까? – nos

답변

0

이 작은 조각 코드의 스택에있는 주소 (로컬 변수의 주소)를 가져 오는 것 같습니다. 레지스터에 넣고, 1보다 큰지 확인한 후 점프를 실행합니다.

하지만 GCC는 거의 모든 주소이 1보다 크기 때문에, 문자 그대로 1에 주소를 비교하는 경우에 jmp 아마 ja만큼이나 잘 작동 할 이유를 확실히 모르겠습니다. 그래서 아마도 ebp 레지스터를 사용하여 스택의 주소가 아닌 다른 것을 보관할 수 있습니까?

어쨌든 엄밀히 말하면 단순한 점프가 아닙니다.

+0

에서 왔지만 "JMP"명령으로 작동합니다. 이유 중 하나는 컴파일러가 항상 뛰어 내릴 것이라고 확신하는 것입니다. switch 문은 다루기가 매우 어렵습니다. – bingosxs

+0

당신 말이 맞아요.나는 당신의 질문에 정말로 대답하지 않았습니다. 그것은 단순한 점프와 같은 결과를 가지고 있지만 더 많은 공간과 시간이 필요한 것을 사용할 것입니다. 가능성은 일반적인 주소가 아니지만, 오프셋 (offset), 그리고 'lea'가 산술을하기 위해 사용되는 ebp에 뭔가가 있다는 것입니다. 이 경우 점프가 실패 할 수 있습니다. – Tony

+0

예. 'ebp '는 주소가 아니라 일반적인 값입니다. \t 명령어가 있습니다 :''cmpl \t $ 8289, % ebp'' – bingosxs