I have been trying to use the C library with NASM, but it isn't working out. I get "Undefined reference to WinMain@16" errors from ld. To link the object file outputted from NASM, I am using gcc -o [filename].exe [filename].o I figure this is a linking error, does anyone know what I should be doing?
20 replies to this topic
#1
Posted 02 January 2011 - 09:57 AM
Latinamne loqueris?
|
|
|
#2
Posted 02 January 2011 - 10:33 AM
#3
Posted 02 January 2011 - 03:27 PM
What was the problem?
#4
Posted 02 January 2011 - 03:34 PM
I don't really know, there was just some linking error, so I took the easy way out: I made a C file that looked like this:
extern void SomeFuncName(void);
int main()
{
SomeFuncName();
}
and in the assembly file I made the SomeFuncName function global (using the global keyword), assembled it to an ELF object file, and linked it like this:gcc [Output from assembler].o [C file].c
Latinamne loqueris?
#5
Posted 03 January 2011 - 08:22 PM
Use the extern keyword in your NASM code where you have your global declarations and stuff.
sudo rm -rf /
#6
Posted 04 January 2011 - 02:37 PM
That is the first thing I tried, and it gave me that undefined reference. I haven't tried making an extern statement for WinMain though, maybe I should.
Latinamne loqueris?
#7
Posted 04 January 2011 - 04:54 PM
Try disassembling the code, if possible, maybe the function name (that you access, referenced by the keyword extern) is different from what it needs to be. I don't know if this is the case, but I sometimes got things like:
C code:
But when I disassembled the code and the function name, instead of being gcd, was ?gcd@@YAHHH@Z.
Another thing is maybe the function name, in global form (from the C code), might actually be _function_name, instead of function_name, (with leading underscore), but NASM assembles it so it references 'function_name', instead of '_function_name'.
So anyway, I think you could try figuring out the actual object code function label name and type 'extern _whatever_the_function_name_is' and then, if you want to, use '%define whatever_the_function_name_is _whatever_the_function_name_is'.
I'm not sure if this is the problem, though, but you could try this.
C code:
int gcd(int a, int b){
.....and so on.....
But when I disassembled the code and the function name, instead of being gcd, was ?gcd@@YAHHH@Z.
Another thing is maybe the function name, in global form (from the C code), might actually be _function_name, instead of function_name, (with leading underscore), but NASM assembles it so it references 'function_name', instead of '_function_name'.
So anyway, I think you could try figuring out the actual object code function label name and type 'extern _whatever_the_function_name_is' and then, if you want to, use '%define whatever_the_function_name_is _whatever_the_function_name_is'.
I'm not sure if this is the problem, though, but you could try this.
#8
Posted 04 January 2011 - 05:19 PM
#9
Posted 05 January 2011 - 03:35 PM
It worked when I defined it as _main! But I didn't clean up the stack after calling _printf, how do I do that?
BTW It appears you were using the Digital Mars compiler for that, RhetoricalRuvim.
BTW It appears you were using the Digital Mars compiler for that, RhetoricalRuvim.
Latinamne loqueris?
#10
Posted 05 January 2011 - 03:40 PM
Not sure how Microsoft does it, but the way GCC does it is like this:
That way you don't have to clean up after every function call.
myfunc: ; create the standard stack frame push ebp mov ebp, esp ; Save enough space on the stack to pass all arguments to all functions and ; keep stack variables as well. If you only call functions with 3 arguments ; or less, then subtract 12, as in this example. sub esp, 12 ; ... blah ... mov DWORD [esp], format_string mov DWORD [esp + 4], 1234 mov DWORD [esp + 8], 5678 call printf ; ... blah ... add esp, 12 ; MAKE SURE THIS IS THE SAME AS ABOVE pop ebp ret
That way you don't have to clean up after every function call.
sudo rm -rf /
#11
Posted 05 January 2011 - 03:57 PM
It works now, thanks! It is possible to just push the arguments and then add the size of all the arguments put together after the call though, isn't it?
Latinamne loqueris?
#12
Posted 05 January 2011 - 04:53 PM
Maybe something like (not sure if it's the best way, though):
About adding the size of the arguments, you mean something like this?:
I usually do it like this, though:
function: enter 12, 0 ;; ..... leave ret
About adding the size of the arguments, you mean something like this?:
function: enter 12, 0 push dword 1234 push word 5678 call some_function add esp, 6 leave ret some_function: ;; some code ..... ret
I usually do it like this, though:
function: enter 12, 0 push dword 1234 push word 5678 call some_function leave ret some_function: enter 4, 0 ;; some code leave ret 6That way the RET instruction takes care of the adding 6 to the stack pointer.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account


Back to top









