please help AHHHH ld and gcc problem ?

Programming, for all ages and all languages.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

please help AHHHH ld and gcc problem ?

Post by Sam111 »

Ok so my problem is that I am trying to call a c function from an assembly file.
I am using gcc to compile and ld to link. I am on windows XP intel 4 processor

Asm file
name = callfunc.asm

Code: Select all

BITS 16
jmp start 
greetings	    db	'Greetings and welcome ',13d,10d,'$' 
extern _write_string
start:
mov ax , 25d
mov bx , greetings
push ax
push bx
call _write_string                 ;[color=#FF0000]This is where I call the c function[/color]
label2:
jmp label2
The c file has just one function in it
name = video.c

Code: Select all


/* note this example will always write to the top
   line of the screen */
void write_string(int colour, const char *string)
{
	volatile char *video=(volatile char*)0xB8000;
	while(*string!=0)
	{
		*video=*string;
		string++;
		video++;
		*video=colour;
		video++;
	}
	return ;
}

I first compile the asm with nasm -f (elf , obj , a.out...) callfunc.asm
and then compile the video.c with gcc -c video.c.
They both compile fine regard less of what I give to -f.
However when I try linking these with ld callfunc.o video.c
I either get

Code: Select all


C:\ASM_PR~1>ld callfunc.o video.o
callfunc.o: file not recognized: File format not recognized

or

C:\ASM_PR~1>ld callfunc.o video.o
c:/djgpp/bin/ld.exe: warning: cannot find entry symbol start; defaulting to 0000
18d0

I kind of know what the problem is but don't know how to fix it.
Is their away to tell gcc to compile to obj , or elf ,or aout because I cann't find the switch for it?
Also maybe I should change it to

Code: Select all

BITS 32 ; really could be 16 or 32 
segment data
greetings	    db	'Greetings and welcome ',13d,10d,'$' 
segment code
extern _write_string
..start:
mov ax , 25d
mov bx , greetings
push ax
push bx
call _write_string
label2:
jmp label2  ;loop for ever an us task manger to kill process.
And compile with nasm -f obj callfunc.asm
But then I run back into the problem of what format gcc -c video.c is an how to change it to obj.
I think gcc only supports elf , coff , macho or a.out , bin or hex formats not obj that is used to create .exe files in windows. I also thought of creating a com file but com files are bin files with org 100h and nasm does not support external references in bin format. WTF , I just want to beable to create an exe that calls my asm function.
ipsemet
Posts: 14
Joined: Mon Dec 01, 2008 6:50 pm

Re: please help AHHHH ld and gcc problem ?

Post by ipsemet »

I had a similar problem when I updated to newest Mingw, though my problem was in reverse (trying to use externally compiled ASM functions in C).

I had originally used A.OUT format, but when I tried to link with newest ld, it refused to work.

Same problem when using cygwin, of course.

Sorry to say that I haven't the slightest clue how to work around it. =/
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: please help AHHHH ld and gcc problem ?

Post by JamesM »

Hi,

You're calling 32-bit protected mode flat-address space code (that generated by GCC) from 16-bit (probably) real-mode code.

Also, GCC on windows (cygwin) creates PE object files. You need to create a cross compiler.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: please help AHHHH ld and gcc problem ?

Post by Sam111 »

I am using djgpp\bin 's gcc under windows xp. What I don't get is how you change the output object format
when I do gcc -c video.c what format is it produceing for the output video.o is it elf , coff ,...
And how do I tell it what format to produce?

On the otherside I am on window so I need to either create a exe or com. But I cann't use a com format because this is a bin format with org 100h and nasm doesn't support external references in bin format.
So that leaves me with creating an .exe but then I would think I would need the obj format.

But I don't think gcc supports obj format. The closes thing is coff but I am not to familar with it.

I Did change the BITS 16 to BITS 32 in callfunc.asm compiled fine but when I try link it no luck.

Is Obj and coff the only object formats that when linked produce a PE windows compatible .exe.
Or can you use elf , a.out.

I just tried nasm -f coff callfunc.asm and ld callfunc.o video.o and it gave me an a.out file WTF is this format
is it a PE like can I do ld -o callfunc.exe callfunc.o video.o . I did it and it produced the .exe and then when I ran it it crashed. I am assuming a.out ,coff, and elf are simliar?

my nasm supports only these formats

Code: Select all

valid output formats for -f are (`*' denotes default):
  * bin       flat-form binary files (e.g. DOS .COM, .SYS)
    aout      Linux a.out object files
    aoutb     NetBSD/FreeBSD a.out object files
    coff      COFF (i386) object files (e.g. DJGPP for DOS)
    elf32     ELF32 (i386) object files (e.g. Linux)
    elf       ELF (short name for ELF32)
    elf64     ELF64 (x86_64) object files (e.g. Linux)
    as86      Linux as86 (bin86 version 0.3) object files
    obj       MS-DOS 16-bit/32-bit OMF object files
    win32     Microsoft Win32 (i386) object files
    win64     Microsoft Win64 (x86-64) object files
    rdf       Relocatable Dynamic Object File Format v2.0
    ieee      IEEE-695 (LADsoft variant) object file format
    macho     NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
As you can see I think my only -f choices on windows xp 32 bit machine is coff , obj , win32.
But the ld linker still complains about me not defining a entry point. But when I use
..start nasm complains about unrecognized special symbol ..start <- this is what the obj format supports for defining it's starting entry point. But apparently nasms documents say that some formats don't support ..start.

Questions
Is their a way to list all supported formats that ld can handle?
Is their a way to list all supported formats that gcc can handle ?
In my video.c file does this function only work if I am in kernal mode or can you use a pointer to video memory in user mode ? Thus if kernel mode is the case then that would explain why my program is crashing.
Do I need different segments or code , data , stack OK? Or does it have to be rodata , text , data , stack ...
Never know what names to call the standard segments.
I have try compiling with nasm and gcc then link with microsofts link linker
link /ENTRY:start /SUBSYSTEM:WINDOWS callfunc.o video.o
This worked and created an exe file how every it is crashing when running it.

Maybe I don't need gcc and can use microsoft cl compiler and nasm -f obj and
link /ENTRY:start /SUBSYSTEM:WINDOWS .
But then again I still want to know why it is crashing do I not have all the proper segment names correct?
I would think the compiler/linker would default to a certain default size if it is missing a needed segment like say stack either way I can define it if needed to.

This is the current callfunc.asm file

Code: Select all

BITS 32
segment data
greetings	    db	'Greetings and welcome ',13d,10d,'$' 
segment code
global _start
_start:
mov ax , 25d
lea bx , [greetings]
push ax
push bx
extern _write_string
call _write_string
label2:
jmp label2
am I calling the function without poping or pushing something? [-o<

For -f win32 or obj what is the difference is this just PE exe to old exe format
http://www.delorie.com/djgpp/doc/exe/

Either way I am confused. In theory a linker takes the object files and merges each data section , code section , ...etc of the object files together and creates the entry point of the starting of the program alone with resolving all the references with the approprate offsets and address. The compiler/assemblier is just to
take the source code and turn it into machine code it is the linkers job to merge everything an resolve symbols and address...etc

So I would think you can compile the code any way you want obj , elf , coff ...etc provided you compile all the files with the same object format. Then if the linker supports linking these object file's and the option of of specifying your target output format. PE .exe then you should be all set. The problem is I don't know what format the ld linker produces by default and how to change it.
I would think maybe the input object format determines the output executable file format but if you can specify a target output independent of what the input object format was to the linker then please tell me how.

It would be cool to do some thing like nasm -f elf prog1.asm ,nasm -f elf prog2.asm ,
nasm -f elf prog3.asm ... etc then do ld -b "PE FORMAT" -o mype.exe prog1.o , prog2.o ,...etc etc
instead of having to use a specific object format to get ld to produce a specific executable format.

AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH WTF WTF WTF sorry I am just frustrated. #-o
Also, GCC on windows (cygwin) creates PE object files. You need to create a cross compiler.
So no matter what object files I use the linker will will create PE exe. But then WTF is the -b target output for in the ld switches. And I thought gcc is a cross compiler ?
So then in theory if what your saying is correct then if I take an elf file and an obj file I can use
ld -o mype myelf.o myobj.obj and it will merge the 2 different object formats into one nice PE. So never have to worry about what object format the file is I can just worry about if their is a unquie entry point.
But then I want to know how I can produce an exe file that linux can run is this what -b is for do I just specify if it is windows or linux , ....etc ect and by default ld outputs for the platform you are running on.
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: please help AHHHH ld and gcc problem ?

Post by ru2aqare »

As far as I know the Windows ports of gcc default to COFF output format (they support other output formats if you cross-compile them). Thus, you have to specify COFF (or compatible) output format for nasm as well. Don't know how to do that - I don't use nasm. Furthermore, I don't know of any linkers that accept some input files in one format (ELF) and others in another format (COFF), so this probably holds to your linker as well. I would recommend sticking with COFF if you are on Windows and don't feel recompiling the complete toolchain, and convert the resulting binary to whatever format you need (or just stick with PE - come on, it isn't that bad or that hard to use).
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: please help AHHHH ld and gcc problem ?

Post by Sam111 »

Thus, you have to specify COFF (or compatible) output format for nasm as well. Don't know how to do that - I don't use nasm.
To answer your question nasm -f coff will do it ?

But then I have to specify an entry point for ld so i used the -e option to specify the "start" is the entry point. This produces an .exe but I don't know if it is a PE or regular exe or what type of exe it is.
I do know it is crashing each time I try to run it.

How do I like tell gcc to compile to coff ?
I have gcc -c video.c (is this producing elf , coff , obj what by default and how to change it???)
I use the -c switch to only compile and assembly but not to link. Because I need to link the nasm file as well so I do it with ld. Should I do it will something like gcc all in on statement and not use -c switch.
I think it will do the same thing?

These are what the gcc supports seems like coff is what it is probably compiling video.c to

Code: Select all

BFD header file version 2.13
coff-go32
 (header little endian, data little endian)
  i386
coff-go32-exe
 (header little endian, data little endian)
  i386
a.out-i386
 (header little endian, data little endian)
  i386
srec
 (header endianness unknown, data endianness unknown)
  i386
symbolsrec
 (header endianness unknown, data endianness unknown)
  i386
tekhex
 (header endianness unknown, data endianness unknown)
  i386
binary
 (header endianness unknown, data endianness unknown)
  i386
ihex
 (header endianness unknown, data endianness unknown)
  i386

               coff-go32 coff-go32-exe a.out-i386 srec symbolsrec tekhex
          i386 coff-go32 coff-go32-exe a.out-i386 srec symbolsrec tekhex

               binary ihex
          i386 binary ihex

or just stick with PE - come on, it isn't that bad or that hard to use
But I thought you said ld its producing PE and only PE for it's output format. And you would need a cross compiler/linker to do a different executable format.
Then I said I thought gcc was a cross compiler?

Maybe you mean if I didn't use the -c and just used gcc to compile and link then it would be always a PE.

Still crashing here is the programs
video.c

Code: Select all

/* note this example will always write to the top
   line of the screen */
void write_string(int colour, const char *string)
{
	volatile char *video=(volatile char*)0xB8000;
	while(*string!=0)
	{
		*video=*string;
		string++;
		video++;
		*video=colour;
		video++;
	}
	return ;
}

Code: Select all

BITS 32
segment data
greetings	    db	'Greetings and welcome ',13d,10d,'$' 
segment code
global _start
_start:
mov ax , 25d
lea bx , [greetings]
push ax
push bx
extern _write_string
call _write_string             [color=#FF0000] Calling video.c function is their something I didn't push ??[/color]
label2:
jmp label2
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: please help AHHHH ld and gcc problem ?

Post by ru2aqare »

Sam111 wrote:To answer your question nasm -f coff will do it ?
Probably. As I said, I am not familiar with nasm.
Sam111 wrote: This produces an .exe but I don't know if it is a PE or regular exe or what type of exe it is.
I do know it is crashing each time I try to run it.
Of course it crashes - it is an OS kernel, not a Win32 application. The instant you access the video memory (which is located below 1M, and is not mapped anywhere by the Windows application loader), you get a page fault. Since you don't have a SEH handler installed, eventually the exception is propagated back to kernel32.dll or ntdll.dll and it terminates your "application". Or, if I read the assembly code correctly, it assumes a 16 bit environment, which does not hold, as the CPU expects 32 bit instructions - instant crash probably due to invalid opcodes. Or the entry point RVA is left undefined (zero) by the linker, which will be mapped to the DOS image header (the MZ bytes) - another reason it crashes.
Sam111 wrote: How do I like tell gcc to compile to coff ?
I think it produces COFF files.
Sam111 wrote:
or just stick with PE - come on, it isn't that bad or that hard to use
But I thought you said ld its producing PE and only PE for it's output format. And you would need a cross compiler/linker to do a different executable format.
Then I said I thought gcc was a cross compiler?
Not sure what you mean here. It probably produces PE, so use PE. Or cross-compile ld and the you can specify additional output formats.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: please help AHHHH ld and gcc problem ?

Post by Solar »

See GCC Cross-Compiler. It does fix many problems to use one, among others it will put you on an identical footing with e.g. Linux users, so they can help you too.
Is their a way to list all supported formats that ld can handle?
ld -V
Is their a way to list all supported formats that gcc can handle ?
as --target-help
In my video.c file does this function only work if I am in kernal mode or can you use a pointer to video memory in user mode ? Thus if kernel mode is the case then that would explain why my program is crashing.
As a rule, nothing that "works in kernel mode" will work in user mode and vice versa. At least, not without you being aware of it because you have gone to great lengths yourself to make it possible.
Do I need different segments or code , data , stack OK? Or does it have to be rodata , text , data , stack ...
You "need" .text and .data. Stack isn't a binary segment of its own (think for a minute, the stack is a dynamic data storage that's build at runtime, so it doesn't reside on file). Usually object files contain a .rodata segment, which you should put into the .text segment of your binary by means of a linker script. Check out Bare bones.
Every good solution is obvious once you've found it.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: please help AHHHH ld and gcc problem ?

Post by Sam111 »

I am not trying to write an os right now I just want to call a c function from asm program in user mode.

If you cannot directly use a pointer to address 0xB8000 (video memory ) in user mode then I will just try a function that just adds 2 numbers or something.
I just want to see it work.

Code: Select all

/* note this example will always write to the top
   line of the screen */
void write_string(int colour, const char *string)
{
   volatile char *video=(volatile char*)0xB8000;
   while(*string!=0)
   {
      *video=*string;
      string++;
      video++;
      *video=colour;
      video++;
   }
   return ;
}

I do get a exe but it just crashes so I don't know if it is a bug in my program or if it is not linking correctly (or not correct exe format)?
Does anybody know if this function is vaild to call in user mode. Or if I made a mistake in not pushing or poping something before or after I call the write_string function?

I think the only thing that could be wrong is I am over looking something in the code (or some user kernal mode issue).

Thanks for any help

Code: Select all

_start:
mov ax , 25d
lea bx , [greetings]
push ax
push bx
extern _write_string
call _write_string   
do I push ax or bx first I think I push the last parameter first so bx then ax?
and since the first argment is type int and the last is string. I would think I ned dw for ax and a address for the pointer in bx. I am using ax ,bx because an int is 16 bits WORD. But I don't know about the address. I am confused on what to push and if the return of the write_string does the poping of the stack?

Maybe this is why I am getting the program crash ??? That is the only last thing it could be other then the rodata ,...etc that I don't get which sections I need to create for a PE. I have always just done asm with stack , data , code segments ???
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: please help AHHHH ld and gcc problem ?

Post by ru2aqare »

Sam111 wrote:

Code: Select all

_start:
mov ax , 25d
lea bx , [greetings]
push ax
push bx
extern _write_string
call _write_string   
do I push ax or bx first I think I push the last parameter first so bx then ax?
That depends on the C compiler. Most compilers support different calling conventions. msvc has stdcall and cdecl (and fastcall, which I have never used). I expect gcc to support at least these two. On x86, both calling conventions work like this: all arguments, starting from the right-most argument, are pushed on the stack. Then the function is called. If your function builds a stack frame, then you can access the first (left-most) argument as [ebp+8], the second as [ebp+12], and so on. The only difference is that in stdcall the function removes the arguments, while in cdecl all arguments are always removed by the caller. This means that for variable-argument functions (like printf) you have to use cdecl, since the function called cannot know how many arguments were passed to it. On x64, there are larger differences. msvc uses a modification of cdecl, where the first four arguments are always passed in rcx, rdx, r8 and r9, however they are also pushed on the stack (or dummy values are pushed on the stack, it does not matter). Gcc has a similar convention with different register assignments.

However, if you compile and run your program under Win32, it may crash because the linker (or the loader) does not support 16-bit relocations like the one used in "lea bx , [greetings]". Neither the gnu nor the MS linker supports them in the first place, which is why I had to write my own linker. Apart from the fact that your arguments are pushed in the wrong order for a C function, and are pushed as 16-bit items on a 32-bit stack, the code seems correct.

So, I would rewrite your code like this:

Code: Select all

extern _write_string
public _start

_start:
push 25
push offset greetings
call _write_string   
add esp, 2*4 ; remove arguments if you use cdecl calling convention, ignore if stdcall
retn 12 ; return to caller (=Windows)  - exit the application
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: please help AHHHH ld and gcc problem ?

Post by Sam111 »

Ok, I will try it when I get home.
remove arguments if you use cdecl calling convention, ignore if stdcall
Do you need to for the program not to crash. I would think if you only call one function it would be ok to leave everything on the stack. I would think this only applies to
if you call alot of functions you could eventually get a stack overflow. As good practice I think I should pop it off the stack after the c function returns to the asm code.

So I should use eax , ebx (32 bit ) as opposed to ax , bx (16 bits ) But the value of an int is 16 bits. So I would be pushing a 32 bit register with a 16 bit value in it?
Won't I always be wasting 2 bytes of space when I push an int and 3 bytes when I push a char ??? But maybe you have to have that space.

I was wondering if you could save some space by using 16 bit registers but then I am thinking that if the program is 32 bit it will only ever be push and poping 32 bit registers (it will only be using 32 bit registers...)

What about if I changed my asm program to 16 bits then I would think I would have to push and pop 16 bit registers everytime?
Wondering if it is possible to compile the above video.c file to 16 bit code and then assembly 16 bit asm program and use ax , bx ,..etc etc?
Never compiled using gcc or cl to 16 bits wondering if it is possible.

Anyway thanks, I will try what you said and for the segments from the asm program what should I create. I have code (which I think is the same as text) , data , stack .
Do I need any others I think the gcc/ld creates them if they aren't their by default. But if the PE needs more user defined sections/segments please let me know.


Yes I am going to use linker scripts latter when I code an os but now I am just trying out how to call c from asm. I know how to already call inline asm from c.
Just trying to go the other way.
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: please help AHHHH ld and gcc problem ?

Post by ru2aqare »

Sam111 wrote: Do you need to for the program not to crash. I would think if you only call one function it would be ok to leave everything on the stack. I would think this only applies to
if you call alot of functions you could eventually get a stack overflow. As good practice I think I should pop it off the stack after the c function returns to the asm code.
It is not a "good practice", it is what the C compiler expects. If you don't conform to the expectations of the C compiler, something is bound to break sooner or later. But as I said, each compiler has its own calling convention.
Sam111 wrote: So I should use eax , ebx (32 bit ) as opposed to ax , bx (16 bits ) But the value of an int is 16 bits. So I would be pushing a 32 bit register with a 16 bit value in it?
Won't I always be wasting 2 bytes of space when I push an int and 3 bytes when I push a char ??? But maybe you have to have that space.
I think it is actually faster to push 32 bit values on a 32bit stack (you want this code to run in 32-bit protected mode, right?) than a 16-bit value. Anyway, you would not save any stack space by using 16-bit operands as the processor automatically expands them to 32 bits.
Sam111 wrote: What about if I changed my asm program to 16 bits then I would think I would have to push and pop 16 bit registers everytime?
Wondering if it is possible to compile the above video.c file to 16 bit code and then assembly 16 bit asm program and use ax , bx ,..etc etc?
Never compiled using gcc or cl to 16 bits wondering if it is possible.
If you intend to use real mode or 16-bit protected mode, then you have to (should) use 16-bit registers. It's what the C compilers expect. Apart from that, I don't know which compiler to use to generate 16-bit assembly output. Probably Borland C.
Sam111 wrote: Anyway thanks, I will try what you said and for the segments from the asm program what should I create. I have code (which I think is the same as text) , data , stack .
Do I need any others I think the gcc/ld creates them if they aren't their by default. But if the PE needs more user defined sections/segments please let me know.
PE doesn't do "segments". It has sections, and different sections may have different protection attributes (but don't need to have). Like ".text" segments are usually read-only, ".data" is read-write, ".rdata" (which stores read-only data, like string constants) is read-only. The stack is created by the loader, you can't specify a section for it. The initial and maximum stack size is determined from values in the PE header.
Sam111 wrote: Yes I am going to use linker scripts latter when I code an os but now I am just trying out how to call c from asm. I know how to already call inline asm from c.
Just trying to go the other way.
When you call assembly code from C, be careful not to destroy the nonvolatile registers - C code expects that these remain constant, and the function called does not modify them (or modifies them transparently, by saving them first and restoring them upon exiting the function). These are usually ebx, esi, edi and ebp on x86, and rbx, rsi, rdi, rbp, r12-r15 on x64. While theoretically different compilers may use different nonvolatile registers, as far as I know all compilers use these register sets.
This applies to the case when you call C code from your assembly code - you can rely on the fact that these registers won't be changed when the called function returns. Thus you can use it to optimize your assembly code - frequently used values could be placed into these registers for example.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: please help AHHHH ld and gcc problem ?

Post by Sam111 »

Ok I change the video.c to this function that I know will run in user mode if called correctly.

Code: Select all

#include <stdio.h>

void printit(int i , const char * string )
{
printf( string ) ;
return ;
}
and the asm

Code: Select all

BITS 32
segment data
greetings	    db	'Greetings and welcome ',13d,10d,'$' 
segment code
global _start
_start:
mov eax , 25d
lea ebx , [greetings]
push ebx
push eax

extern _printit
call _printit
label2:
jmp label2
I compile with nasm -f coff callfunc.asm then I do gcc -c video.c .
Then I do ld -e start callfunc.o video.o which gives me

Code: Select all

video.o : error LNK2001: unresolved external symbol _printf
callfunc.exe : fatal error LNK1120: 1 unresolved externals
Do I have to give it the path of printf dll file or something thought it would find it since it is in stdio.h?
Whats the switch for this in ld or gcc. I always use to set it in the IDE of visual studio's so I never need tio bother with command line path stuff I would think I need to link with libc .

When I try using microsofts linker link and cl I get this
I get

Code: Select all

LIBC.lib(wwincrt0.obj) : error LNK2001: unresolved external symbol _wWinMain@16
callfunc.exe : fatal error LNK1120: 1 unresolved externals
I know the problem is that it cann't resolve the printf even though I included stdio.h ?
What can I do to fix this?
Is this like a pragma statement thing I need or can I specifiy it command line?
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: please help AHHHH ld and gcc problem ?

Post by ru2aqare »

Sam111 wrote:Ok I change the video.c to this function that I know will run in user mode if called correctly.

Code: Select all

#include <stdio.h>

void printit(int i , const char * string )
{
printf( string ) ;
return ;
}
and the asm

Code: Select all

BITS 32
segment data
greetings	    db	'Greetings and welcome ',13d,10d,'$' 
segment code
global _start
_start:
mov eax , 25d
lea ebx , [greetings]
push ebx
push eax

extern _printit
call _printit
label2:
jmp label2
The code seems correct, with the addition that printf (like all of the standard C string-handling functions) expects a zero-terminated, and not a '$'-terminated string (like MSDOS).
Sam111 wrote: I compile with nasm -f coff callfunc.asm then I do gcc -c video.c .
Then I do ld -e start callfunc.o video.o which gives me

Code: Select all

video.o : error LNK2001: unresolved external symbol _printf
callfunc.exe : fatal error LNK1120: 1 unresolved externals
Do I have to give it the path of printf dll file or something thought it would find it since it is in stdio.h?
Of course. You reference an external function, but don't provide the code for it - the linker refuses to link the file, since it would be incomplete without the actual printf function. If execution would somehow reach the 'call printf' statement, it likely would crash, since the machine code would be E8 00 00 00 00, 'call near $+5'. In other words, it would call the instruction immediately after it, pushing extra doublewords on the stack.
Sam111 wrote: Whats the switch for this in ld or gcc. I always use to set it in the IDE of visual studio's so I never need tio bother with command line path stuff I would think I need to link with libc .
Can't help you there. Use 'man gcc' or something similar. Or just google it.
Sam111 wrote: When I try using microsofts linker link and cl I get this
I get

Code: Select all

LIBC.lib(wwincrt0.obj) : error LNK2001: unresolved external symbol _wWinMain@16
callfunc.exe : fatal error LNK1120: 1 unresolved externals
I know the problem is that it cann't resolve the printf even though I included stdio.h ?
What can I do to fix this?
Is this like a pragma statement thing I need or can I specifiy it command line?
It is the same error. You reference the printf function, but don't provide a definition for it. One solution is to use the C runtime library provided with gcc or msvc. I can't recall what command-line arguments to pass to achieve this, but it most definitely can be done. If you use VS, just create an empty Win32 project, and check what are the settings in the Project Properties dialog box.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: please help AHHHH ld and gcc problem ?

Post by Solar »

I get the impression that you are horribly confused.

Sometimes its best to clean your workbench and start over. Tabula rasa. Focussing on the first minute step, not trying to do too much at once.

Create a new working directory.

Write this in myFunc.c:

Code: Select all

#include <stdio.h>

extern void asmFunc();

void myFunc()
{
    puts( "Hello" );
}

int main()
{
    asmFunc();
}
Compile to object code:

Code: Select all

gcc -c myFunc.c -o myFunc.o
Now write this to myAsm.asm:

Code: Select all

BITS 32
segment code
global _asmFunc
_asmFunc:
extern _myFunc
call _myFunc
label:
jmp label
Assemble:

Code: Select all

nasm -f coff myAsm.asm
Link:

Code: Select all

gcc myAsm.o myFunc.o
Execute:

Code: Select all

./a.exe
Now step back, look at the steps above, and understand - really understand - what is happening there. (It's working on my Cygwin setup here, if it gives an error on your setup we can work on that.)

Then make the further steps - writing main() in ASM, for example.
Every good solution is obvious once you've found it.
Post Reply