Search code examples
c++assemblyx86masm

Why does the output of my program keep changing? EAX register keeps changing value?


I wrote a program to find the length of the largest increasing sequence given a larger array(the array is initialized in c++ and the c++ main calls the procedure), I got the code compiled, however, the output of the program keeps changing?

I tried replacing and observing the registers, and they don't seem to have an effect on the program output at all.

Finally, I tried to delete all the instructions inside the procedure that would affect the ret (returns EAX), however, the program still output random integers on the console

Sequence.asm (.asm file)

.586
.MODEL flat,C


.data
.code




    longestSequence PROC USES  eax ebx esi edi ,theArrayOFFSET: PTR DWORD,theArraySize: DWORD
    LOCAL temp[10]: DWORD 
    LOCAL lengthc: DWORD
    LOCAL k: DWORD  
    LOCAL temp1: DWORD 
    LOCAL temp2: DWORD 



//the algorithm to find the longest sequence of integer should be here, but its not shown for simplicity and the program still output random integers

*
*
*
mov eax,8 //suppose I move 8 into eax, it still generates random output

ret
longestSequence ENDP


END 
Class ConsoleApplication3(cpp file)

#include "pch.h"
#include <iostream>

extern "C" int longestSequence(int array[], unsigned count);

int main()
{
    int array1[10] = { -5, 10, 20, 14, 17, 26, 42, 22, 19, -5 };
    int seq;


    seq = longestSequence(array1, 10);
    cout << seq << endl;
    return 0;
}

The output varies each time the program runs, for example: 1st run - 7338264 2nd run - 19920684

The correct output for array1 = { -5, 10, 20, 14, 17, 26, 42, 22, 19, -5 }; should be 4 because the length of the longest sequence is 4 for {14,17,26,42}


Solution

  • PROC USES eax causes MASM to generate prologue code that saves eax on the stack when the function begins, and also epilogue code that restores its original value before each ret. This obliterates any value that you prepare in eax before exiting your function.

    In other words, your

    mov         eax,8  
    ret
    

    in actually translated into

    mov         eax,8  
    pop         edi  
    pop         esi  
    pop         ebx  
    pop         eax  
    leave  
    ret  
    

    (In the calling code eax is probably used to temporarily store some address value. Address space randomization causes it to change from one session to another, which is what randomizes the value that you observe.)

    Remove eax from USES list.