Asm to C and Back
Asm to C and Back
OK, I am going give it a shot to ask this question here.
I have a boot loader written in asm using NASM, (I don't use GRUB), I don't use ELF, I am working on a Windows System for Windows, and I am assembling my loader using a flat-binary format. My problem is I am not able to use ORG or EXTERN when using the flat-binary format, so my question is:
Keeping with the same flat-binary format, how can I call an external function in my C Kernel from my ASM boot loader and vice versa?
Thanks
I have a boot loader written in asm using NASM, (I don't use GRUB), I don't use ELF, I am working on a Windows System for Windows, and I am assembling my loader using a flat-binary format. My problem is I am not able to use ORG or EXTERN when using the flat-binary format, so my question is:
Keeping with the same flat-binary format, how can I call an external function in my C Kernel from my ASM boot loader and vice versa?
Thanks
Hi,
Why can't you use ORG? This works for me in NASM.
To call a C function, from ASM, you need to know what linkage your compiler uses. If it is GCC, the 32 bit default is to push all arguments right-to-left, then do a call. The caller removes pushed arguments. If you don't have a properly set up cross compiler and don't use a command line switch, you may find that gcc adds a leading underscore to the c function names. In this way, 'main' becomes '_main'. So, to call main:
To call ASM from C, it's fairly easy - you just have to handle the pushed registers nicely - generally, you use ebp to mark the function's 'stack frame'.
In 64 bit mode, all this changes and parameters are passed in registers be default. See the System V ABI for details.
Cheers,
Adam
Why can't you use ORG? This works for me in NASM.
To call a C function, from ASM, you need to know what linkage your compiler uses. If it is GCC, the 32 bit default is to push all arguments right-to-left, then do a call. The caller removes pushed arguments. If you don't have a properly set up cross compiler and don't use a command line switch, you may find that gcc adds a leading underscore to the c function names. In this way, 'main' becomes '_main'. So, to call main:
Code: Select all
push eax ;argv
push ebx ;argc
call [main] ;or call [_main]
pop ebx
pop eax ;caution about this - gcc returns the first integer parameter in eax!
In 64 bit mode, all this changes and parameters are passed in registers be default. See the System V ABI for details.
Cheers,
Adam
-
- Member
- Posts: 566
- Joined: Tue Jun 20, 2006 9:17 am
This should be helpful
Hope that this http://atrevida.comprenica.com/atrtut19.html helps
@AJ AND SandeepMathew: Thanks for your replies they were helpful.
@Combuster: Then how would you set up my compilation script:
thanks
@Combuster: Then how would you set up my compilation script:
Code: Select all
@echo off
set PATH=c:\djgpp\bin;%PATH%
set DJGPP=c:\djgpp\djgpp.env
chdir c:\djgpp\toy os\src
call del.bat
nasm-2.01rc1\nasm -w-orphan-labels -f bin x86boot.asm -o x86boot.bin
c:\djgpp\bin\gcc -ffreestanding -c -o main.o main.c
c:\djgpp\bin\gcc -c video.c -o video.o
c:\djgpp\bin\gcc -c ports.c -o ports.o
c:\djgpp\bin\ld -e _main -Ttext 0x1000 -o kernel.o main.o video.o ports.o
c:\djgpp\bin\ld -i -e _main -Ttext 0x1000 -o kernel.o main.o video.o ports.o
c:\djgpp\bin\objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin
c:\djgpp\bin\makeboot a.img x86boot.bin kernel.bin
pause
why do you need to 'call' the C code from your bootloader, why don't you just jump to either a second-stage bootloader and then use the 'extern' feature, or just jump straight to your C code?
Why don't you load your binary off of the floppy and then jump to it wherever you placed it?
Why don't you load your binary off of the floppy and then jump to it wherever you placed it?
Website: https://joscor.com
@01000101 (E): Nice! I like that, secondary boot loader. I could treat it as an object and do all my stuff from there. I wouldn't mind writing my stuff in asm like the GDT/IDT stuff, but my reason for needing to call some code in my loader is so that I can flush the GDT/IDT when I use it with IO. I do everything else in C, however.
@combuster: does PE == coff in NASM?
@mods: why haven't you hacked the forum to show the posts to these threads as we create/edit posts? I kept forgetting the names of the people I was trying to respond to, plus I would forget what they even said and it sucks to have to keep going back and forth between pages. I'll write you a solution if necessary just to make my life easier while I am here. Hope you get it fixed.
@combuster: does PE == coff in NASM?
@mods: why haven't you hacked the forum to show the posts to these threads as we create/edit posts? I kept forgetting the names of the people I was trying to respond to, plus I would forget what they even said and it sucks to have to keep going back and forth between pages. I'll write you a solution if necessary just to make my life easier while I am here. Hope you get it fixed.
Update: OK, somehow I managed to make it assemble without changing anything.. just yesterday I wasn't able to use extern or global and today I can?
Well, here is what I am trying to do:
That is a section of my boot loader. I placed in the jmp to show that I have already jmp'd to my kernel, then in my kernel:
I do that, but when I assemble I get this:
So, what am I doing wrong?
Well, here is what I am trying to do:
Code: Select all
jmp 08h:01000h ; Jump to section 08h (code), offset 01000h
[GLOBAL test]
test:
jmp$
Code: Select all
extern void test();
void main()
{
printf("blah");
test();
}
So, it assembled and linked, but when I run it I see the text "blah" and get a system crash; which tells me that my assembler code is not being called, or else it would hang thus being the equivalent of C's for(;;);main.o:main.c:(.text+0x6f): undefined reference to `test'
1 sectors, 512 bytes read from file x86boot.bin...
2 sectors, 1008 bytes read from file kernel.bin...
Press any key to continue . . .
So, what am I doing wrong?
- bloodhound23
- Member
- Posts: 115
- Joined: Wed Jan 23, 2008 7:13 pm
- Contact:
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
The problem is that you must make two different programs be able to talk with one another. That means you'll need some way to have one program know where to reach the other program. Given the level in which you are, we can pretty much rule out dynamic linking and system calls.
The only two real options I can see is not to call a bootloader from the kernel. Probably the best thing.
The other option is to not make two programs, but rather one, which essentially means that you put the kernel and bootloader in a single binary so that at least LD can figure where everything's located.
Given the fact that you do not seem to know in detail how your tools work, I really suggest you review the architecture of your system. Once you exit the bootloader you should not be coming back.
@bloodhound23: you do not need to use fasm to get a flat binary. nasm/yasm can do those natively as well. You can even assemble with gas and use ld to create a flat binary.
The only two real options I can see is not to call a bootloader from the kernel. Probably the best thing.
The other option is to not make two programs, but rather one, which essentially means that you put the kernel and bootloader in a single binary so that at least LD can figure where everything's located.
Given the fact that you do not seem to know in detail how your tools work, I really suggest you review the architecture of your system. Once you exit the bootloader you should not be coming back.
@bloodhound23: you do not need to use fasm to get a flat binary. nasm/yasm can do those natively as well. You can even assemble with gas and use ld to create a flat binary.
@combuster: OK, that is what I thought, if I jmp outside the loader I would not be able to reference the code inside it anymore, it makes sense to me that it works that way, which is why I included that line in my example for the hopes that someone would notice it and know right away what I am doing wrong, and you did.
No, I don't care what my level is, tell me what is right to do, not what is possible for me right now! I want to know what should be done. I know since I code for Windows, that makes me an outcast in this community. Many of the guides and tips do not apply to me, mainly the ones that use ELF and GRUB, which is nearly all!! However, it is the code I care about. You are not born knowing how to do this kind of thing, so it is helpful to learn from others which is why I ask so many questions. It isn't like I will be new forever, I learn fast enough, but only when I am being taught the right thing and in the right way. One line replies do nothing for me, I am a hands-on learner.
I hope that I can co-exist here peacefully, I promise to not burden you too much with my obsessive questioning.. lol
Anyway, I guess I will just ask someone else. thanks
P.s. How do I delete my account or can you do it for me?
No, I don't care what my level is, tell me what is right to do, not what is possible for me right now! I want to know what should be done. I know since I code for Windows, that makes me an outcast in this community. Many of the guides and tips do not apply to me, mainly the ones that use ELF and GRUB, which is nearly all!! However, it is the code I care about. You are not born knowing how to do this kind of thing, so it is helpful to learn from others which is why I ask so many questions. It isn't like I will be new forever, I learn fast enough, but only when I am being taught the right thing and in the right way. One line replies do nothing for me, I am a hands-on learner.
I hope that I can co-exist here peacefully, I promise to not burden you too much with my obsessive questioning.. lol
Anyway, I guess I will just ask someone else. thanks
P.s. How do I delete my account or can you do it for me?
jmp 08h:01000h ; Jump to section 08h (code), offset 01000h
shouldn't this be:
asm
C
shouldn't this be:
asm
Code: Select all
global _test
_test:
hlt
ret
Code: Select all
extern void test();
void main()
{
printf("blah");
test();
}
Website: https://joscor.com
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Well, if you expected it, why didn't you tell us? You probably didn't mean it like that, but we rather help people who are straight and have looked for an answer rather than one playing games asking questions trying to figure who knows the right answer. That feels like wasting my time.newwen wrote:@combuster: OK, that is what I thought, if I jmp outside the loader I would not be able to reference the code inside it anymore, it makes sense to me that it works that way, which is why I included that line in my example for the hopes that someone would notice it and know right away what I am doing wrong, and you did.
I think we just hit the spot where your skill "level" is indeed important. Programming for windows is hardly the same thing as programming an OS. I regularly program for windows too (I even won competitions with windows apps), but I don't think I'm an outcast here, merely strange (*cough* freebasic *cough*). An operating system is *not* windows, an OS does *not* run under windows. Instead it runs on bare metal. You have no task manager that can kill your program when it goes awry. Knowing what GRUB can do for you is the start of your quest. Knowing what ELF and PE are allows you to make your own choice. That both do not apply to you is nonsense. You should know them to make an educated decision about using them or not.No, I don't care what my level is, tell me what is right to do, not what is possible for me right now! I want to know what should be done. I know since I code for Windows, that makes me an outcast in this community. Many of the guides and tips do not apply to me, mainly the ones that use ELF and GRUB, which is nearly all!! However, it is the code I care about. You are not born knowing how to do this kind of thing, so it is helpful to learn from others which is why I ask so many questions. It isn't like I will be new forever, I learn fast enough, but only when I am being taught the right thing and in the right way. One line replies do nothing for me, I am a hands-on learner.
Seriously, people never learn to work on their own if we keep feeding them the answers. Rather, they should try and understand how things work and then put that knowledge to good use. Going somewhere else to be fed with the answers doesn't help you in the long run.Anyway, I guess I will just ask someone else. thanks
You can't, I can't.P.s. How do I delete my account or can you do it for me?