Attempt to rebuild a function

I am trying to understand the build in x86 yet. I have a secret function that I know returns intand accepts an argument int. So he looks like int mystery(int n){}. However, I cannot understand the function in C. Build:

mov  %edi, %eax
lea  0x0(,%rdi, 8), %edi
sub  %eax, %edi
add  $0x4, %edi
callq < mystery _util >
repz retq

< mystery _util >
mov  %edi, %eax
shr  %eax
and  $0x1, %edi
and  %edi, %eax
retq

I don’t understand what lea is doing here and what function can be.

+2
source share
3 answers

, , , -, , , 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
+7

LEA - 3, 32 ( EDI RDI implicilty). x86-64 V arg RDI, int. LEA - shift-and-add. x86.

, , ; mov

lea  0x0(,%rdi, 8), %eax     # n << 3 = n*8
sub  %edi, %eax              # eax = n*7
lea  4(%rax), %edi           # rdi = 4 + n*7

n*7 %edi, , , , .


mystery_util 2 , 0 1 , bool.

(shr 1, , x86 1. 8086 1 cl; .)

+2

LEA , . AT & T lea C(b,c,d), reg reg = C + b + c*d, C - , b, C - , d - {1,2,4,8}. , , LEA : . (* prl )

: repz , retq ( - ), . . lea (,rdi,8), edi, sub eax, edi arg1 * 7, , , prl , d 2. , ,

mov  %edi, %eax          ; eax = arg1
lea  0x0(,%rdi, 8), %edi ; edi = arg1 * 8
sub  %eax, %edi          ; edi = (arg1 * 8) - arg1 = arg1 * 7
add  $0x4, %edi          ; edi = (arg1 * 7) + 4
callq < mystery _util >  ; call mystery_util(arg1 * 7 + 4)
repz retq                ; repz prefix on return is de facto nop.


< mystery _util >
mov  %edi, %eax          ; eax = arg1
shr  %eax                ; eax = arg1 >> 1
and  $0x1, %edi          ; edi = 1 iff arg1 was odd, else 0
and  %edi, %eax          ; eax = 1 iff smallest 2 bits of arg1 were both 1.
retq

, +4 4- . mystery_util.

, ASM (arg1 * 7)% 4 == 3.

+1

Source: https://habr.com/ru/post/1695027/


All Articles