Move twice from and to, the same location

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite












I'm trying to reverse a function and i came across this lines inside the function



1. call ds:HeapAlloc
2. mov [ebp+var_4], eax
3. mov eax, [ebp+var_4]



Why does line 3 needed?




If i need to save the result line 2 saved that and EAX already have the result,
So why is line 3 needed.



Am i missing something?










share|improve this question









New contributor




Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1




    It might be that the binary is not optimized and the line 3 is part of the next instruction that uses the HeapAlloc’s result
    – Paweł Łukasik
    2 hours ago










  • @PawełŁukasik even if it's in used in the next instruction EAX already has the result/
    – Moshe D
    2 hours ago














up vote
2
down vote

favorite












I'm trying to reverse a function and i came across this lines inside the function



1. call ds:HeapAlloc
2. mov [ebp+var_4], eax
3. mov eax, [ebp+var_4]



Why does line 3 needed?




If i need to save the result line 2 saved that and EAX already have the result,
So why is line 3 needed.



Am i missing something?










share|improve this question









New contributor




Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1




    It might be that the binary is not optimized and the line 3 is part of the next instruction that uses the HeapAlloc’s result
    – Paweł Łukasik
    2 hours ago










  • @PawełŁukasik even if it's in used in the next instruction EAX already has the result/
    – Moshe D
    2 hours ago












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I'm trying to reverse a function and i came across this lines inside the function



1. call ds:HeapAlloc
2. mov [ebp+var_4], eax
3. mov eax, [ebp+var_4]



Why does line 3 needed?




If i need to save the result line 2 saved that and EAX already have the result,
So why is line 3 needed.



Am i missing something?










share|improve this question









New contributor




Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I'm trying to reverse a function and i came across this lines inside the function



1. call ds:HeapAlloc
2. mov [ebp+var_4], eax
3. mov eax, [ebp+var_4]



Why does line 3 needed?




If i need to save the result line 2 saved that and EAX already have the result,
So why is line 3 needed.



Am i missing something?







ida disassembly






share|improve this question









New contributor




Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 2 hours ago





















New contributor




Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 hours ago









Moshe D

1113




1113




New contributor




Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Moshe D is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 1




    It might be that the binary is not optimized and the line 3 is part of the next instruction that uses the HeapAlloc’s result
    – Paweł Łukasik
    2 hours ago










  • @PawełŁukasik even if it's in used in the next instruction EAX already has the result/
    – Moshe D
    2 hours ago












  • 1




    It might be that the binary is not optimized and the line 3 is part of the next instruction that uses the HeapAlloc’s result
    – Paweł Łukasik
    2 hours ago










  • @PawełŁukasik even if it's in used in the next instruction EAX already has the result/
    – Moshe D
    2 hours ago







1




1




It might be that the binary is not optimized and the line 3 is part of the next instruction that uses the HeapAlloc’s result
– Paweł Łukasik
2 hours ago




It might be that the binary is not optimized and the line 3 is part of the next instruction that uses the HeapAlloc’s result
– Paweł Łukasik
2 hours ago












@PawełŁukasik even if it's in used in the next instruction EAX already has the result/
– Moshe D
2 hours ago




@PawełŁukasik even if it's in used in the next instruction EAX already has the result/
– Moshe D
2 hours ago










2 Answers
2






active

oldest

votes

















up vote
1
down vote













It's not needed at all.



However, some compilers may generate that assembly when compiled without optimization.



For example, gcc -O0 generates: (from godbolt)



f():
push rbp
mov rbp, rsp
sub rsp, 16
call fake_heapalloc()
mov DWORD PTR [rbp-4], eax
mov eax, DWORD PTR [rbp-4]
mov edi, eax
call g(int)
nop
leave
ret


from C++ source code



int fake_heapalloc();
void g(int i);
void f()
int i;
i=fake_heapalloc();
g(i);



Because it's not optimized, the i is stored on the stack (instead of in a register) and the redundant move to/from stack code is generated.




Alternatively, some programmer may manually insert the assembly instruction there to... I don't know, it's unlikely.






share|improve this answer




















  • (this contains essentially the same information as other answers, just worded in a different way)
    – user202729
    21 mins ago

















up vote
1
down vote













This is to save the value on the stack and continue to work with that value in further instruction(s) as already mentioned in the comments. This happens if no optimization is done.



You have to look at it separately.
Consider this in pseudocode.



var_4 = HeapAlloc()
func1(var_4)


Then the result would be similar to your assembler output namely:



1. call ds:HeapAlloc
2. mov [ebp+var_4], eax
3. mov eax, [ebp+var_4]
4. push eax
5. call func1


And in that case you are right, the value is still in eax.



But now consider that:



var_4 = HeapAlloc()
between_func()
func1(var_4)


The assembler output would be similar to this



1. call ds:HeapAlloc
2. mov [ebp+var_4], eax
3. call between_func
4. mov eax, [ebp+var_4]
5. push eax
6. call func1


You can refer a pseudocode line to a section of the assembler code.




var_4 = HeapAlloc()




Corresponds to:



1. call ds:HeapAlloc
2. mov [ebp+var_4], eax



between_func()




Corresponds to:



3. call between_func



func1(var_4)




Corresponds to:



4. mov eax, [ebp+var_4]
5. push eax
6. call func1


And if you omit the between_func() then you will get to the result you have. Concluded, the two instructions are compiled independently.






share|improve this answer










New contributor




pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "489"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    noCode: true, onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    Moshe D is a new contributor. Be nice, and check out our Code of Conduct.









     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2freverseengineering.stackexchange.com%2fquestions%2f19488%2fmove-twice-from-and-to-the-same-location%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    It's not needed at all.



    However, some compilers may generate that assembly when compiled without optimization.



    For example, gcc -O0 generates: (from godbolt)



    f():
    push rbp
    mov rbp, rsp
    sub rsp, 16
    call fake_heapalloc()
    mov DWORD PTR [rbp-4], eax
    mov eax, DWORD PTR [rbp-4]
    mov edi, eax
    call g(int)
    nop
    leave
    ret


    from C++ source code



    int fake_heapalloc();
    void g(int i);
    void f()
    int i;
    i=fake_heapalloc();
    g(i);



    Because it's not optimized, the i is stored on the stack (instead of in a register) and the redundant move to/from stack code is generated.




    Alternatively, some programmer may manually insert the assembly instruction there to... I don't know, it's unlikely.






    share|improve this answer




















    • (this contains essentially the same information as other answers, just worded in a different way)
      – user202729
      21 mins ago














    up vote
    1
    down vote













    It's not needed at all.



    However, some compilers may generate that assembly when compiled without optimization.



    For example, gcc -O0 generates: (from godbolt)



    f():
    push rbp
    mov rbp, rsp
    sub rsp, 16
    call fake_heapalloc()
    mov DWORD PTR [rbp-4], eax
    mov eax, DWORD PTR [rbp-4]
    mov edi, eax
    call g(int)
    nop
    leave
    ret


    from C++ source code



    int fake_heapalloc();
    void g(int i);
    void f()
    int i;
    i=fake_heapalloc();
    g(i);



    Because it's not optimized, the i is stored on the stack (instead of in a register) and the redundant move to/from stack code is generated.




    Alternatively, some programmer may manually insert the assembly instruction there to... I don't know, it's unlikely.






    share|improve this answer




















    • (this contains essentially the same information as other answers, just worded in a different way)
      – user202729
      21 mins ago












    up vote
    1
    down vote










    up vote
    1
    down vote









    It's not needed at all.



    However, some compilers may generate that assembly when compiled without optimization.



    For example, gcc -O0 generates: (from godbolt)



    f():
    push rbp
    mov rbp, rsp
    sub rsp, 16
    call fake_heapalloc()
    mov DWORD PTR [rbp-4], eax
    mov eax, DWORD PTR [rbp-4]
    mov edi, eax
    call g(int)
    nop
    leave
    ret


    from C++ source code



    int fake_heapalloc();
    void g(int i);
    void f()
    int i;
    i=fake_heapalloc();
    g(i);



    Because it's not optimized, the i is stored on the stack (instead of in a register) and the redundant move to/from stack code is generated.




    Alternatively, some programmer may manually insert the assembly instruction there to... I don't know, it's unlikely.






    share|improve this answer












    It's not needed at all.



    However, some compilers may generate that assembly when compiled without optimization.



    For example, gcc -O0 generates: (from godbolt)



    f():
    push rbp
    mov rbp, rsp
    sub rsp, 16
    call fake_heapalloc()
    mov DWORD PTR [rbp-4], eax
    mov eax, DWORD PTR [rbp-4]
    mov edi, eax
    call g(int)
    nop
    leave
    ret


    from C++ source code



    int fake_heapalloc();
    void g(int i);
    void f()
    int i;
    i=fake_heapalloc();
    g(i);



    Because it's not optimized, the i is stored on the stack (instead of in a register) and the redundant move to/from stack code is generated.




    Alternatively, some programmer may manually insert the assembly instruction there to... I don't know, it's unlikely.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 21 mins ago









    user202729

    2367




    2367











    • (this contains essentially the same information as other answers, just worded in a different way)
      – user202729
      21 mins ago
















    • (this contains essentially the same information as other answers, just worded in a different way)
      – user202729
      21 mins ago















    (this contains essentially the same information as other answers, just worded in a different way)
    – user202729
    21 mins ago




    (this contains essentially the same information as other answers, just worded in a different way)
    – user202729
    21 mins ago










    up vote
    1
    down vote













    This is to save the value on the stack and continue to work with that value in further instruction(s) as already mentioned in the comments. This happens if no optimization is done.



    You have to look at it separately.
    Consider this in pseudocode.



    var_4 = HeapAlloc()
    func1(var_4)


    Then the result would be similar to your assembler output namely:



    1. call ds:HeapAlloc
    2. mov [ebp+var_4], eax
    3. mov eax, [ebp+var_4]
    4. push eax
    5. call func1


    And in that case you are right, the value is still in eax.



    But now consider that:



    var_4 = HeapAlloc()
    between_func()
    func1(var_4)


    The assembler output would be similar to this



    1. call ds:HeapAlloc
    2. mov [ebp+var_4], eax
    3. call between_func
    4. mov eax, [ebp+var_4]
    5. push eax
    6. call func1


    You can refer a pseudocode line to a section of the assembler code.




    var_4 = HeapAlloc()




    Corresponds to:



    1. call ds:HeapAlloc
    2. mov [ebp+var_4], eax



    between_func()




    Corresponds to:



    3. call between_func



    func1(var_4)




    Corresponds to:



    4. mov eax, [ebp+var_4]
    5. push eax
    6. call func1


    And if you omit the between_func() then you will get to the result you have. Concluded, the two instructions are compiled independently.






    share|improve this answer










    New contributor




    pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      1
      down vote













      This is to save the value on the stack and continue to work with that value in further instruction(s) as already mentioned in the comments. This happens if no optimization is done.



      You have to look at it separately.
      Consider this in pseudocode.



      var_4 = HeapAlloc()
      func1(var_4)


      Then the result would be similar to your assembler output namely:



      1. call ds:HeapAlloc
      2. mov [ebp+var_4], eax
      3. mov eax, [ebp+var_4]
      4. push eax
      5. call func1


      And in that case you are right, the value is still in eax.



      But now consider that:



      var_4 = HeapAlloc()
      between_func()
      func1(var_4)


      The assembler output would be similar to this



      1. call ds:HeapAlloc
      2. mov [ebp+var_4], eax
      3. call between_func
      4. mov eax, [ebp+var_4]
      5. push eax
      6. call func1


      You can refer a pseudocode line to a section of the assembler code.




      var_4 = HeapAlloc()




      Corresponds to:



      1. call ds:HeapAlloc
      2. mov [ebp+var_4], eax



      between_func()




      Corresponds to:



      3. call between_func



      func1(var_4)




      Corresponds to:



      4. mov eax, [ebp+var_4]
      5. push eax
      6. call func1


      And if you omit the between_func() then you will get to the result you have. Concluded, the two instructions are compiled independently.






      share|improve this answer










      New contributor




      pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



















        up vote
        1
        down vote










        up vote
        1
        down vote









        This is to save the value on the stack and continue to work with that value in further instruction(s) as already mentioned in the comments. This happens if no optimization is done.



        You have to look at it separately.
        Consider this in pseudocode.



        var_4 = HeapAlloc()
        func1(var_4)


        Then the result would be similar to your assembler output namely:



        1. call ds:HeapAlloc
        2. mov [ebp+var_4], eax
        3. mov eax, [ebp+var_4]
        4. push eax
        5. call func1


        And in that case you are right, the value is still in eax.



        But now consider that:



        var_4 = HeapAlloc()
        between_func()
        func1(var_4)


        The assembler output would be similar to this



        1. call ds:HeapAlloc
        2. mov [ebp+var_4], eax
        3. call between_func
        4. mov eax, [ebp+var_4]
        5. push eax
        6. call func1


        You can refer a pseudocode line to a section of the assembler code.




        var_4 = HeapAlloc()




        Corresponds to:



        1. call ds:HeapAlloc
        2. mov [ebp+var_4], eax



        between_func()




        Corresponds to:



        3. call between_func



        func1(var_4)




        Corresponds to:



        4. mov eax, [ebp+var_4]
        5. push eax
        6. call func1


        And if you omit the between_func() then you will get to the result you have. Concluded, the two instructions are compiled independently.






        share|improve this answer










        New contributor




        pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        This is to save the value on the stack and continue to work with that value in further instruction(s) as already mentioned in the comments. This happens if no optimization is done.



        You have to look at it separately.
        Consider this in pseudocode.



        var_4 = HeapAlloc()
        func1(var_4)


        Then the result would be similar to your assembler output namely:



        1. call ds:HeapAlloc
        2. mov [ebp+var_4], eax
        3. mov eax, [ebp+var_4]
        4. push eax
        5. call func1


        And in that case you are right, the value is still in eax.



        But now consider that:



        var_4 = HeapAlloc()
        between_func()
        func1(var_4)


        The assembler output would be similar to this



        1. call ds:HeapAlloc
        2. mov [ebp+var_4], eax
        3. call between_func
        4. mov eax, [ebp+var_4]
        5. push eax
        6. call func1


        You can refer a pseudocode line to a section of the assembler code.




        var_4 = HeapAlloc()




        Corresponds to:



        1. call ds:HeapAlloc
        2. mov [ebp+var_4], eax



        between_func()




        Corresponds to:



        3. call between_func



        func1(var_4)




        Corresponds to:



        4. mov eax, [ebp+var_4]
        5. push eax
        6. call func1


        And if you omit the between_func() then you will get to the result you have. Concluded, the two instructions are compiled independently.







        share|improve this answer










        New contributor




        pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        share|improve this answer



        share|improve this answer








        edited 5 mins ago





















        New contributor




        pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered 1 hour ago









        pudi

        538




        538




        New contributor




        pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        pudi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.




















            Moshe D is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            Moshe D is a new contributor. Be nice, and check out our Code of Conduct.












            Moshe D is a new contributor. Be nice, and check out our Code of Conduct.











            Moshe D is a new contributor. Be nice, and check out our Code of Conduct.













             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2freverseengineering.stackexchange.com%2fquestions%2f19488%2fmove-twice-from-and-to-the-same-location%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            Installing NextGIS Connect into QGIS 3?

            One-line joke