繁体   English   中英

为什么gcc会生成“ Leal -8240(%ebp),%eax”; cmpl $ 1,%eax; ja XXX”而不是jmp指令?

[英]why gcc generates “leal -8240(%ebp), %eax; cmpl $1, %eax; ja XXX” instead of jmp instruction?

我正在研究由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中可移植(我不知道任何不支持jmp指令的x86 cpu)

我的原因: ja的下一条指令是.LBB77处的mov指令,而此mov指令对应于第373行的源。如果ja不跳转,则这是跨函数执行。 这是一个非常奇怪的行为,这是无法预期的。 因此,我得出结论,它一定是“ 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 

乍一看,这小段代码似乎是在抓取栈中某个对象的地址(即局部变量的地址),将其放入寄存器中,查看其是否大于1,并仅在以下情况下执行跳转:它是。

但是我不太确定为什么gcc想要将地址与文字1进行比较,因为几乎每个地址都大于1,在这种情况下jmp可能和ja 因此,也许它正在使用ebp寄存器来保存堆栈地址以外的内容?

无论如何,这都不是简单的跳转。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM