Let’s consider this snippet from decompilation of an x86 Windows binary:
The same function is called twice with the same argument and the last one doesn’t seem to use the result of the
By switching to disassembly, we can see that
eax is initialized before each call with a string address:
However the decompiler does not consider it, because on x86 the stack is the usual way of passing arguments and
eax is most commonly just a temporary scratch register.
One option is to edit the prototype of
sub_10006FC7 to use the __usercall calling convention and add
eax to the argument manually. But when the function is situated in the same binary, it is usually easier to simply go inside the function and decompile it so that the decompiler can see that it does use
eax before initializing, and so it is added to the argument list:
esi is also detected to be an argument.
If we go back to the caller now, we should see the previously missing arguments being passed to the calls:
NB: usage of non-standard, custom calling convention is often a sign of either functions using hand-written assembly, or whole program optimization (aka LTO or LTCG) being enabled.