Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 384 Vote(s) - 3.65 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Does the return value always go into eax register after a method call?

#1
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?
Reply

#2
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
Reply

#3
It really depends on the calling convention used, but typically `EAX` is used for 32-bit and smaller integral data types, floating point values tend to use FPU or MMX registers, and 64-bit integral types tend to use a combination of `EAX` and `EDX` instead. Then there is the issue of complex class/struct types, in which case the compiler may decide to optimize away the return value and use an extra output parameter on the call stack to pass the returned object by reference to the caller.
Reply

#4
You are asking questions about the ABI (Application Binary Interface). This varies depending on the operating system. You should look it up. You can find some good info and links to other documents at

[To see links please register here]


To answer your question, yes, as far as I know, all of the popular operating systems use the A register to return the result.
Reply

#5
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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through