Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the return value always go into eax register after a method call?

Tags:

I have written a hooking library, that examines a PE executables dll import table, to create a library that enables changing of parameters and return values. I have a few questions on how the return value is passed from a function.

I have learned that the return value of a function is saved in the accumulator register. Is this always the case? If not, how does the compiler know where to look for the function result?

What about the return type size? An integer will easily fit, but what about a bigger structure? Does the caller reserve stack space so the method it calls could write the result onto stack?

like image 846
Bartlomiej Lewandowski Avatar asked Jan 17 '14 21:01

Bartlomiej Lewandowski


People also ask

Is EAX the return register?

eax (or rax) is the return value register. edi (or rdi) is the first function argument. esi (or rsi) is the second function argument.

What register is the return value in?

Registers EAX, ECX, and EDX are designated for use within the function. Return values are stored in the EAX register. stdcall is the standard calling convention for the Microsoft Win32 API and for Open Watcom C++.

What does EAX register do?

EAX register, a 32-bit processor register of x86 CPUs. Environmental Audio Extensions, a number of digital signal processing presets for audio, found in Sound Blaster sound cards.

What is the value of EAX register?

I know when add integers in assembly, it stores result in the destination. and when we multiply it stores in eax. so if I call the function multiply( 3 , 8 ), the value of eax register after that line should be 120.


2 Answers

It's all specific to calling convention.

For most calling conventions floating point numbers are returned either on FPU-stack or in XMM registers.

Call to the function returning a structure

    some_struct foo(int arg1, int arg2);     some_struct s = foo(1, 2); 

will be compiled into some equivalent of:

    some_struct* foo(some_struct* ret_val, int arg1, int arg2);     some_struct s; // constructor isn't called     foo(&s, 1, 2); // constructor will be called in foo 

Edit: (add info)

just to clarify: this works for all structs and classes even when sizeof(some_struct) <= 4. So if you define small useful class like ip4_type with the only unsigned field and some constructors/convertors to/trom unsigned, in_addr, char* it will lack efficiency compared to use of raw unigned value.

like image 67
qwm Avatar answered Sep 18 '22 15:09

qwm


If the function get inlined, the result is not saved in eax, also if results are passed by reference/pointer, that register won't be used.

look at what happens to a function that return doubles (on a 32 bit machine)

double func(){     volatile double val=5.0;     return val; }  int main(){     double val = func();     return 0; } 

doubles are not in eax.

func():     pushq   %rbp     movq    %rsp, %rbp     movabsq $4617315517961601024, %rax     movq    %rax, -8(%rbp)     movq    -8(%rbp), %rax     movq    %rax, -24(%rbp)     movsd   -24(%rbp), %xmm0     popq    %rbp     ret main:     pushq   %rbp     movq    %rsp, %rbp     subq    $24, %rsp     call    func()     movsd   %xmm0, -24(%rbp)     movq    -24(%rbp), %rax     movq    %rax, -8(%rbp)     movl    $0, %eax     leave     ret 
like image 20
CoffeDeveloper Avatar answered Sep 22 '22 15:09

CoffeDeveloper