I am studying the assembly code generated by the gcc. However, I found the following code fragment:
.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
By investigating the soure code, I discover that this should be a jmp instruction. Why gcc compiler use 3 instructions instead of 1 instruction? Is it more efficient or it is portable among the X86 cpu(I do not know any x86 cpu not supporting the jmp instruction)
MY REASON: The next instruction of ja is a mov instruction at .LBB77 and this mov instruction corresponding to the source at line 373. If ja does not jump, then this is a cross-function execution . This is a very bizarre behaviour and is not expected. Therefore I concluded it must be a "jmp".
FINAL RESULTS: This is NOT a jmp. It may run the instructions of line 373 in the source. CLOSED.
============================ more information:
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
At first glance, this small piece of code seems to be grabbing the address of something on the stack -- the address of a local variable -- putting it in a register, seeing if it is greater than 1, and executing the jump only if it is.
But I am not quite sure why gcc would want to compare the address to the literal 1
, because nearly every address is greater than 1, in which case jmp
would probably work just as well as ja
. So perhaps it is using the ebp
register to hold something other than the address of the stack?
In any case, it is not strictly a simple jump.