So I have the following code in assembly:
I know that the parameters for the function are two (x and y or any letter). The problem is that I don't know how to see from the assembly code whether the function is returning anything since it only says ret
. Would this function be considered void or int? Any explanation for understanding would be well appreciated.
CodePudding user response:
Both is possible. You cannot in general tell if a value is to be returned or not just form looking at the code of the function. For more certainty, look for functions that call this function and check if these functions inspect the return value. If any of them does, there is a return value. If not, there is likely no return value.
CodePudding user response:
The return value is passed in the register eax / rax, if needed.
Since that register is modified, first reading from the variable x
, then adding to the other variable, both cases are possible. In the void
case, the eax
register can contain any value, not limited to *x
.
void f(int *x, int *y) {
*y = *x;
}
int g(int *x, int *y) {
int z = *x;
*y = z;
return z;
}
As a counter-example,
void h(int x, int *y) { *y = x; }
add %esi, (%rdi)
ret
would clearly have void
as the only possible signature.
A clear indicator of int
return value OTOH is when there are no side effects (such as stores) after the last modification of eax/rax
- no reasonable optimizing compiler would produce such a code, however a reasonable obfuscating compiler possibly would.
CodePudding user response:
In high-level languages there is generally a formal notion of a function. Functions have features like:
A signature — describing parameters & return value type
Many languages also allow optional parameters (usually with default values supplied if the caller doesn't specify)
A number of languages allow variable parameters, usually after fixed parameters
Either a return value type or void — but not both
Limited to a single entry point
Multiple possible return points — that must all return the same type
Most of the above amounts to restrictions/limitations that tell us what we cannot do, and these constraints allow the language implementations to catch errors at build time, while also preventing certain chaos (hard to find bugs) at runtime.
These formalizations were, in part, developed after years of experience with assembly language, which is lacking these formalizations, and hence these restrictions/limitations.
In assembly code, there is no formalization of the notion of function. Thus, there are fewer rules to break, you can:
- Have multiple entry points
- Have different signatures for the same function
- Return different types of values (including void) from different return spots
- Jump from one function to another without invoking the function properly
- etc..
Would this function be considered void or int?
We don't actually know for certain, as assembly, especially disassembly doesn't offer that information.
The