Thread: C code understandings conversion to assembly (MIPS)

  1. #1
    Registered User
    Join Date
    Jan 2024
    Posts
    25

    C code understandings conversion to assembly (MIPS)

    Hi ,
    I totally understand the recursion in C programming and now trying more further to understand what is going behind the scenes , so trying please to have the conversion on assembly language for this chunk of code ( just for more understandings not more ) .

    C code is :

    Code:
    int divide(int a)
    {
       if ( a > 1 )
       {
         return divide(a/2);
        }
       return a;
    }
    Could anyone please help me for conversion this code to assembly language?
    like normally Im not programming on assembly language and learnt it long long time ago but trying to understand only
    the recursion part how it's done on assembly behind.


    thanks much
    Last edited by AkamiKhmenisky; 02-01-2024 at 11:50 AM.

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Simple:

    Code:
    $ gcc -S divide.c
    
    // divide.s
    
            .file   "divide.c"
            .text
            .globl  divide
            .type   divide, @function
    divide:
    .LFB0:
            .cfi_startproc
            pushq   %rbp
            .cfi_def_cfa_offset 16
            .cfi_offset 6, -16
            movq    %rsp, %rbp
            .cfi_def_cfa_register 6
            subq    $16, %rsp
            movl    %edi, -4(%rbp)
            cmpl    $1, -4(%rbp)
            jle     .L2
            movl    -4(%rbp), %eax
            movl    %eax, %edx
            shrl    $31, %edx
            addl    %edx, %eax
            sarl    %eax
            movl    %eax, %edi
            call    divide
            jmp     .L3
    .L2:
            movl    -4(%rbp), %eax
    .L3:
            leave
            .cfi_def_cfa 7, 8
            ret
            .cfi_endproc
    .LFE0:
            .size   divide, .-divide
            .ident  "GCC: (Debian 13.2.0-10) 13.2.0"
            .section        .note.GNU-stack,"",@progbits

  3. #3
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by rstanley View Post
    Simple:
    Not MIPS...

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Quote Originally Posted by flp1969 View Post
    Not MIPS...
    MIPS cross compile with gcc.

    I don't use MIPS.

  5. #5
    Registered User
    Join Date
    Apr 2021
    Posts
    140
    Try Compiler Explorer -- Matt Godbolt's "Compiler Explorer" website. You can select a MIPS compiler, and choose which one you like best, then generate assembly from whatever C code you post up.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > the recursion part how it's done on assembly behind.
    Exactly the same way one function would call another.

    Nothing changes except for the name of the called function.

    For recursive functions, you end up with 3 cases - depending on the function and how smart the compiler is.
    1. A recursive call
    2. Tail call elimination, the call becomes a jump back to the start - Tail call - Wikipedia
    3. Complete elimination of any looping at all.

    For example, your divide reduces to this at -O2
    Code:
    divide(int):
            test    edi, edi
            mov     eax, 1
            cmovle  eax, edi
            ret
    No recursion, no loops, just the trivial answer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    In other words, the compiler you used (GCC?) is smart enough to optimize the recursive code to the equivalent to this code:

    Code:
    int divide(int a)
    {
        if (a > 1) {
            return 1;
        }
        return a;
    }

  8. #8
    Registered User
    Join Date
    Jan 2024
    Posts
    25
    Quote Originally Posted by christop View Post
    In other words, the compiler you used (GCC?) is smart enough to optimize the recursive code to the equivalent to this code:

    Code:
    int divide(int a)
    {
        if (a > 1) {
            return 1;
        }
        return a;
    }
    why if (a>1) then you return 1? my original function is return divide(a/2) ;

  9. #9
    Registered User
    Join Date
    Jan 2024
    Posts
    25
    Quote Originally Posted by Salem View Post
    > the recursion part how it's done on assembly behind.
    Exactly the same way one function would call another.

    Nothing changes except for the name of the called function.

    For recursive functions, you end up with 3 cases - depending on the function and how smart the compiler is.
    1. A recursive call
    2. Tail call elimination, the call becomes a jump back to the start - Tail call - Wikipedia
    3. Complete elimination of any looping at all.

    For example, your divide reduces to this at -O2
    Code:
    divide(int):
            test    edi, edi
            mov     eax, 1
            cmovle  eax, edi
            ret
    No recursion, no loops, just the trivial answer.
    I understand , thanks.



    like what Im trying to understand why we need to avoid generally recursion .. any reason aside to stackover flow case?? there is also another reason which is related to "functions calling overheads" but I didnt get it to be honest if someone can help please ..

    assume I have two following equivalent solutions :

    Code:
    intdivide(inta){
        if (a > 1) {
            return 1;
        }
        return a;
    }
    


    second solution equivalent for first recursion solution is " for loop solution " :

    Code:
    
    
    Code:
    int divide(int a)
    {
    for ( ; a > 1 ; a/=2);
    return a;
    }
    



    why for loop solution is more efficient to use than recursion solutions? what the are the reasons for choosing for loop solution upon recursive? ..

    additional quivery , is the number of iterations of for loop itself is same as the number of functions calling on recursive solution? if yes/no then why ?
    Last edited by AkamiKhmenisky; 02-01-2024 at 05:21 PM.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    There's no reason to avoid it per se, it just comes with a few health warnings - like the aforementioned stack overflow potential.

    Anything you can do with recursion, you can do with a for loop (and a queue data structure if you do need to store intermediate state between iterations).

    > why for loop solution is more efficient to use than recursion solutions?
    There's no function call overhead.

    > what the are the reasons for choosing for loop solution upon recursive? ..
    There's no function call overhead, and no chance of blowing the stack.
    You can write strlen() as a recursive function. You'd be dumb to try it on a real long string though.

    > additional quivery , is the number of iterations of for loop itself is same as the number of functions calling on recursive solution? if yes/no then why ?
    Should be the same, unless you've done something wrong.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Jan 2024
    Posts
    25
    Quote Originally Posted by Salem View Post
    There's no reason to avoid it per se, it just comes with a few health warnings - like the aforementioned stack overflow potential.

    Anything you can do with recursion, you can do with a for loop (and a queue data structure if you do need to store intermediate state between iterations).

    > why for loop solution is more efficient to use than recursion solutions?
    There's no function call overhead.

    > what the are the reasons for choosing for loop solution upon recursive? ..
    There's no function call overhead, and no chance of blowing the stack.
    You can write strlen() as a recursive function. You'd be dumb to try it on a real long string though.

    > additional quivery , is the number of iterations of for loop itself is same as the number of functions calling on recursive solution? if yes/no then why ?
    Should be the same, unless you've done something wrong.
    thanks much , some inline comments as you see below.

    > There's no function call overhead.
    when you say function overhead what do you mean exactly could you elaborate please meaning of function overheads and how that impact stack / time complexity? why for loop doesnt have function overheads?

    >Should be the same, unless you've done something wrong.
    why number of calling functions on recursive shall be same as number of iterations? ... maybe if you can give please calculation how did you validate about that would be much worthy ..

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Write recursive and non-recursive versions of some functions and count for yourself.

    You want to understand - write some code!
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Jan 2024
    Posts
    25
    Quote Originally Posted by Salem View Post
    Write recursive and non-recursive versions of some functions and count for yourself.

    You want to understand - write some code!
    I understand but I already wrote the code for loop solution and recursive solution above , so then what next step shall I do for proving what you're suggesting that recursive call counts same as for loop iterations counts?
    you know we are talking about "n" number so cant count .. it might be that n very huge number yeah ..it's integer ..

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Show us what you have so far.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    Jan 2024
    Posts
    25
    Quote Originally Posted by Salem View Post
    Show us what you have so far.
    first recursive solution
    Code:
    int divide(int a)
    { 
        if (a > 1) {
              return divide (a/2);
                      }
        return a; 
    }
    second equivalent solution by for loop approach :

    Code:
    int divide(int a)
    {
        for( ; a > 1 ; a /=2 );
        return a;
    }
    both solutions are equivalent and this what I reached so far.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ to MIPS Assembly: how to approach
    By primoriscruor in forum C++ Programming
    Replies: 3
    Last Post: 11-29-2012, 08:46 AM
  2. MIPS Assembly Bubble Sort
    By cornfeller in forum Tech Board
    Replies: 17
    Last Post: 06-16-2012, 08:09 PM
  3. convert c programm to mips assembly
    By mariakat in forum Tech Board
    Replies: 8
    Last Post: 02-14-2011, 08:39 PM
  4. Converting C into MIPS Assembly
    By clag in forum C Programming
    Replies: 5
    Last Post: 02-13-2010, 07:48 PM
  5. A question of the MIPS assembly program
    By ok_good in forum Tech Board
    Replies: 0
    Last Post: 05-03-2006, 10:13 PM

Tags for this Thread