0

I have these functions in C++

int f1(int a)
{
    int x = a  / 2; 
}

int f2(int a)
{
    int y = a % 2;
}

 int f3(int a)
 {
    int z = a % 7;
 }

int f4(int a,int b)
 {
   int xy = a % b; 
 }

And i saw their assembly code but couldn't understand what they are doing.I couldn't even find a good referance or some explained example for the same. Here is the assembly

f1(int):
    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-20], edi
    mov     eax, DWORD PTR [rbp-20]
    mov     edx, eax
    shr     edx, 31
    add     eax, edx
    sar     eax
    mov     DWORD PTR [rbp-4], eax
    nop
    pop     rbp
    ret

f2(int):
    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-20], edi
    mov     eax, DWORD PTR [rbp-20]
    cdq
    shr     edx, 31
    add     eax, edx
    and     eax, 1
    sub     eax, edx
    mov     DWORD PTR [rbp-4], eax
    nop
    pop     rbp
    ret

f3(int):
    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-20], edi
    mov     eax, DWORD PTR [rbp-20]
    movsx   rdx, eax
    imul    rdx, rdx, -1840700269
    shr     rdx, 32
    add     edx, eax
    sar     edx, 2
    mov     esi, eax
    sar     esi, 31
    mov     ecx, edx
    sub     ecx, esi
    mov     edx, ecx
    sal     edx, 3
    sub     edx, ecx
    sub     eax, edx
    mov     DWORD PTR [rbp-4], eax
    nop
    pop     rbp
    ret

f4(int, int):
    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-20], edi
    mov     DWORD PTR [rbp-24], esi
    mov     eax, DWORD PTR [rbp-20]
    cdq
    idiv    DWORD PTR [rbp-24]
    mov     DWORD PTR [rbp-4], edx
    nop
    pop     rbp
    ret

Can you please tell by some example or what steps it is following to calculate the answers in all these three cases and why would they work just fine instead of normal divide

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    OP asked about four functions, the "duplicate" question only refers to `f3` – Daniel Kleinstein Aug 10 '21 at 19:10
  • 2
    For the record, I voted to close as "too broad", as there are (too) many questions in this one. – rustyx Aug 10 '21 at 19:27
  • 1
    @DanielKleinstein: There are now 2 duplicates, covering power-of-2 with one, and multiplicative inverse with the other. I guess I could add [Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?](https://stackoverflow.com/q/53366394) for why the asm is slow bloated and clunky even for `f4` (instead of just a couple mov instructions and `cdq`/`idiv`) – Peter Cordes Aug 10 '21 at 19:47
  • 1
    Your functions could be dropped by the compiler since they don't return a value and they are using local variables. Hint: If you don't want a function to return a value, use the `void` return type. If you want to modify the parameters, pass them by reference. – Thomas Matthews Aug 10 '21 at 20:15
  • compile your `foo.cc` C++ file with a recent [GCC](http://gcc.gnu.org/) invoked as `gcc -O -fverbose-asm -S foo.cc` then look into the generated `foo.s` assembler file. You may want to read about [invoking GCC](https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html), and about [GCC internals](https://gcc.gnu.org/onlinedocs/gccint/index.html), and a good compiler textbook, e.g. [the Dragon book](https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools) – Basile Starynkevitch Aug 10 '21 at 20:21

0 Answers0