flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Linking and Calling C function from Assembly

Author
Thread Post new topic Reply to topic
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 09:17
Hello Everyone,

this must have been asked many times in here.. I tried searching but could not find any solution.

I am writing a little OS which will boot, enter protected mode and call C function (transfer control to C program - kernel).

So far I have been able to enter protected mode. Also I am able to read sectors and loan 2nd stage loader and execute it. Now I want to link my obj file generated by fasm with obj file generated by c compiler.

FASM code:

Code:
format COFF
use32
extrn start
call start
    


C code:

Code:
#include <stdio.h>

extern void start( void )
{
        printf ("test");
}
    


I am able to produce obj file for both. When trying to link on windows using LINK.exe (VC++ linker)

I get bellow error:

Code:
LINK : fatal error LNK1561: entry point must be defined
    


Which I understand that it needs entry point, but in my case, my entry point will be assembly and then it will be transferred to c code.

Can someone please help me?

Thanks and Regards,
dhavalhirdhav.


Last edited by dhavalhirdhav on 16 Nov 2019, 09:37; edited 1 time in total
Post 16 Nov 2019, 09:17
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 16 Nov 2019, 09:37
Firstly I'm not good with C, so this might be wrong.

But, when you write a boot sector you don't define an entry point because the output format should be a binary file. That is, it won't be an exe format, so there is no way to define an entry point. The BIOS will simply jump to the first byte of the sector.
Post 16 Nov 2019, 09:37
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 09:38
revolution wrote:
Firstly I'm not good with C, so this might be wrong.

But, when you write a boot sector you don't define an entry point because the output format should be a binary file. That is, it won't be an exe format, so there is no way to define an entry point. The BIOS will simply jump to the first byte of the sector.


Thanks for your reply. I do not have issue with boot sector. Boot sector works fine. Goes into protected.
Post 16 Nov 2019, 09:38
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 16 Nov 2019, 09:41
But you are now trying to link with your boot sector. So the linker wants to know the entry point. But there is no way to define it.

Perhaps you can make a dummy entry point to satisfy the linker. It won't matter what you make it since it is never used.
Post 16 Nov 2019, 09:41
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 09:44
revolution wrote:
But you are now trying to link with your boot sector. So the linker wants to know the entry point. But there is no way to define it.

Perhaps you can make a dummy entry point to satisfy the linker. It won't matter what you make it since it is never used.


aah ok.. that makes sense.

I modified my code like this:

Code:
format COFF
use32
public main as '_main'
extrn _start
main:
    call _start
    


and c code as follows:

Code:
#include <stdio.h>

extern void __cdecl start()
{
        printf ("test");
}
    


This works.. linker is not complaining now. It produces .exe file. .which is Windows executable.. executes but doesnt show any output on screen.

I will see how I can produce obj file out of linker so that I can load that into memory through boot sector.
Post 16 Nov 2019, 09:44
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 16 Nov 2019, 09:47
What library are you using for printf?

Also, I would recommend you make a binary file. Loading obj files is quite tricky. You could do it, but it makes the boot sector needlessly complex.
Post 16 Nov 2019, 09:47
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 09:55
revolution wrote:
What library are you using for printf?


stdio.h

Quote:

Also, I would recommend you make a binary file. Loading obj files is quite tricky. You could do it, but it makes the boot sector needlessly complex.


Any idea how do I produce binary file with fasm and with c compiler? Binary file as in bin files?

If I do bin files in fasm.. I cant use extern keyword right?
Post 16 Nov 2019, 09:55
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 16 Nov 2019, 10:03
stdio.h is for the OS binding. I don't think C has a BIOS version of stdio.

I think to make your binary you would first link the obj files so that the symbol binding is done at that stage. And then you convert it to a binary as the last step.
Post 16 Nov 2019, 10:03
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 10:09
revolution wrote:
stdio.h is for the OS binding. I don't think C has a BIOS version of stdio.

I think to make your binary you would first link the obj files so that the symbol binding is done at that stage. And then you convert it to a binary as the last step.


hmm.. is there any good example of using FASM boot sector to call c method / function?
Post 16 Nov 2019, 10:09
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 16 Nov 2019, 10:15
You don't really need to link your boot sector with the second stage.

You can make your second stage binary have its entry point as the first byte. Or just put a pointer at the first dword and your boot sector can read that to jump to the entry.
Post 16 Nov 2019, 10:15
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 10:48
revolution wrote:
You don't really need to link your boot sector with the second stage.

You can make your second stage binary have its entry point as the first byte. Or just put a pointer at the first dword and your boot sector can read that to jump to the entry.


yes thats what I have done.. my boot sector reads 2nd sector of drive and loads it into memory and jumps to 2nd sector's entry point. I dont link boot sector and second stage.. but now what I want to do is, I dont want to continue with ASM as it will be too difficult, so I want to write kernel in C and 2nd stage should jump to C method.
Post 16 Nov 2019, 10:48
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 16 Nov 2019, 10:52
I was assuming your C code was the second stage. But my comment can still apply if your C code is some other stage. If you only have one symbol to bind then it is quite easy to do. And that way you can update each stage individually without affecting the other stages.
Post 16 Nov 2019, 10:52
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 11:00
revolution wrote:
I was assuming your C code was the second stage. But my comment can still apply if your C code is some other stage. If you only have one symbol to bind then it is quite easy to do. And that way you can update each stage individually without affecting the other stages.


ok.. any pointers.. I have been trying to link since many days and progressing very slow Sad
Post 16 Nov 2019, 11:00
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 16 Nov 2019, 11:11
If we assume your boot sector is at 0:7c00 and you load the second stage C code at 0x10000 then do this:
Code:
use32
;...
jmp 0x10000 ;jump to the first byte and start executing    
Or, it you have a pointer:
Code:
use32
;...
mov eax,[0x10000] ;read the offset
add eax,0x10000 ;add the load address
jmp eax ;execute    
For the C code side of things, I don't know. But you will still need to make a binary from the obj file. But you won't need to link to the assembly.
Post 16 Nov 2019, 11:11
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 16 Nov 2019, 13:22
revolution wrote:
If we assume your boot sector is at 0:7c00 and you load the second stage C code at 0x10000 then do this:
Code:
use32
;...
jmp 0x10000 ;jump to the first byte and start executing    
Or, it you have a pointer:
Code:
use32
;...
mov eax,[0x10000] ;read the offset
add eax,0x10000 ;add the load address
jmp eax ;execute    
For the C code side of things, I don't know. But you will still need to make a binary from the obj file. But you won't need to link to the assembly.


ok.. I first need to figure out way to convert obj file into bin files.
Post 16 Nov 2019, 13:22
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC 16 Nov 2019, 21:38
found this. it's in nasm but if fasm produces object files that are compatible then it should work the same.

https://www.devdungeon.com/content/how-mix-c-and-assembly
Post 16 Nov 2019, 21:38
View user's profile Send private message Visit poster's website Reply with quote
dhavalhirdhav



Joined: 16 Nov 2019
Posts: 9
dhavalhirdhav 18 Nov 2019, 03:43
BAiC wrote:
found this. it's in nasm but if fasm produces object files that are compatible then it should work the same.

https://www.devdungeon.com/content/how-mix-c-and-assembly


yes.. I did it with NASM and gcc linker finally. I really wish FASM could do that.
Post 18 Nov 2019, 03:43
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4347
Location: Now
edfed 18 Nov 2019, 09:25
maybe you can twist this example https://flatassembler.net/examples/msvc.zip to make what you'd like.

here, the c code will call asm code that will call c code.
Post 18 Nov 2019, 09:25
View user's profile Send private message Visit poster's website Reply with quote
donn



Joined: 05 Mar 2010
Posts: 321
donn 18 Nov 2019, 17:18
If you're just building a COFF and mixing with C, think the 32-bit imports look like this:

Code:
extrn '__imp__HeapAlloc@12' as HeapAlloc:dword    


64 is different. The link just provided above should have another import example in there somewhere. msvc is what got me started with COFFs. I think @12 relates to the parameter count sizes. 64 bit does not need them.[/code]
Post 18 Nov 2019, 17:18
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.