, , , -, , , GCC, repz retq (call). , mystery_util (jmp) call, -O1 ( , , , ). / , -O0
x 7 , x 8 x. :
lea 0x0(,%rdi, 8), %edi
sub %eax, %edi
LEA , . - (, , ). 1, 2, 4, 8. - + + * . lea 0x0(,%rdi, 8), %edi EDI = 0x0 + RDI * 8 EDI = RDI * 8. n * 7 - 4;
mystery_util
n &= (n>>1) & 1;
, mystery, n * 7 - 4 , mystery_util, n &= (n>>1) & 1.
mystery_util (0 1), , bool .
, GCC 1 (-O1) . , GCC 4.9.x C:
#include<stdbool.h>
bool mystery_util(unsigned int n)
{
n &= (n>>1) & 1;
return n;
}
bool mystery(unsigned int n)
{
return mystery_util (7*n+4);
}
:
mystery_util:
movl %edi, %eax
shrl %eax
andl $1, %edi
andl %edi, %eax
ret
mystery:
movl %edi, %eax
leal 0(,%rdi,8), %edi
subl %eax, %edi
addl $4, %edi
call mystery_util
rep ret
godbolt.
- bool
, -, . , , , , mystery int mystery(int n). , . , Stackoverflow , , int mystery(int n) . , , .
, , mystery_util. :
mov %edi, %eax
shr %eax
EDI - . SHR - . , EDI unsigned int ( ). int - , SAR ( ). , mystery_util unsigned int ( , , , unsigned int. , :
unsigned int mystery_util(unsigned int n)
{
n &= (n>>1) & 1;
return n;
}
int mystery(int n)
{
return mystery_util (7*n+4);
}
mystery , (bool ), unsigned int mystery_util. GCC 4.9.x, , -O1 -fno-inline. godbolt. bool.
unsigned int mystery_util(int n), , , :
mystery_util:
movl %edi, %eax
sarl %eax ; <------- SAR (arithmetic shift right) is not SHR
andl $1, %edi
andl %edi, %eax
ret