How do I mix C with x86 assembly language?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
stevewoods1986
Member
Member
Posts: 80
Joined: Wed Aug 09, 2017 7:37 am

How do I mix C with x86 assembly language?

Post by stevewoods1986 »

Hello.

I want to mix C with x86 assembly language. However, I don't want it to be compiled into an ELF binary. How would I make it so my C works with my OS?

Here is a simple program.

Code: Select all

main()
{

}
I would like it to act like a label. When I do

Code: Select all

objdump -d hello
It shows the hex values and instructions of an ELF binary (like you would have on Linux). What do I need to do? I've checked out the Mixing Assembly and C article (http://www.osdev.org/howtos/1/index.html) but I'm not using a linker. I'm simply using NASM and disk dump.

Any help would be appreciated.

Thanks
Steve.
User avatar
zaval
Member
Member
Posts: 659
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: How do I mix C with x86 assembly language?

Post by zaval »

What do I need to do?
Learn?
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
stevewoods1986
Member
Member
Posts: 80
Joined: Wed Aug 09, 2017 7:37 am

Re: How do I mix C with x86 assembly language?

Post by stevewoods1986 »

zaval wrote:
What do I need to do?
Learn?
Learn? How do I make GCC compile my C for my OS? I don't think you can't boot an ELF binary with INT 13h. I've tried out -ffreestanding. Do I have to change anything? I want to play with 0xb800 in C. However, I want to make it suitable for my OS.
MichaelPetch
Member
Member
Posts: 799
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: How do I mix C with x86 assembly language?

Post by MichaelPetch »

If the goal is to generate a BINary file, why not generate ELF objects (C and assembly modules) and use a linker to combine them together and then use a linker (with a linker script) and/or a tool like objcopy to convert an elf executable to a binary file?

GCC based tool chains are not a good tool to be doing real-mode development. Consider something like OpenWatcom C that can generate proper 16-bit real mode code. But the question is how much real-mode code are you writing? An entire OS in real mode or just a bootloader that enters protected mode and calls into 32-bit code later on?
User avatar
zaval
Member
Member
Posts: 659
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: How do I mix C with x86 assembly language?

Post by zaval »

stevewoods1986 wrote:
zaval wrote:
What do I need to do?
Learn?
Learn? How do I make GCC compile my C for my OS? I don't think you can't boot an ELF binary with INT 13h. I've tried out -ffreestanding. Do I have to change anything? I want to play with 0xb800 in C. However, I want to make it suitable for my OS.
It's basically wrong to glue your OS with BIOS directly, unless you are writing some dinosaurOS :lol: Make your OS a formatted executable (elf, pe/coff) and make your bootloader load it properly. make your boot loader suitable for interacting with BIOS not OS. you've been already adviced above as to what you should do and use.
I am not messing around with x86, but I have similar needs - I have ROM code which wants a plain binary (my code) at the sector 1 of a storage, it loads it and jumps to it. I make it an elf file first, because my tools only speak elf, >_> and then translate it into a plain binary with the objcopy uitility. something similar should be possible for x86 I guess. also you could use third party loaders like grub or whatever and follow their conventions on loading your kernel. again, it's a bad idea to make your kernel a plain dumb binary messing up with dinosauric BIOS calls. look forward, not backward. :)
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do I mix C with x86 assembly language?

Post by iansjack »

stevewoods1986 wrote:I've checked out the Mixing Assembly and C article (http://www.osdev.org/howtos/1/index.html) but I'm not using a linker.
Well, you have isolated the cause of your problem. The solution is to use a linker. You can then convert the files to raw binary (if you really want to - which is almost certainly a mistake).
stevewoods1986
Member
Member
Posts: 80
Joined: Wed Aug 09, 2017 7:37 am

Re: How do I mix C with x86 assembly language?

Post by stevewoods1986 »

Never mind. It doesn't matter.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: How do I mix C with x86 assembly language?

Post by Schol-R-LEA »

To everyone other than the OP: back up a bit on the attitude and give stevewoods1986 a chance to explain his goals a bit more. He asked fairly specific questions, in both this thread and the one on the text buffer - which is definitely progress IMAO - and responding as if he were still acting the way he did in his first thread is overly hostile even by my standards. Take it down a notch, please.

While I agree that he may be making a mistake in trying to use a raw executable image for the entry point of the OS, we don't know why he plans that, and more importantly, it was only tangentially related to the question, as he will probably need to know how to link multiple executables and produce a raw image from that at some point, for one reason or another.

Furthermore, if you think he's doing something incorrectly, ask first, or at least explain why you think it might be a bad idea - without the snark. Save the snark for people who have proven themselves incapable of listening; the OP has shown he is listening now, so maybe cut him some slack.
Last edited by Schol-R-LEA on Fri Aug 11, 2017 9:17 am, edited 2 times in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do I mix C with x86 assembly language?

Post by iansjack »

You seem to be reading hostility where none is present. If you want to be a moderator then do it properly and contact the site owners.

The OP has been given the correct advice - use the normal tools to compile and link the program and then convert it to a raw binary if required. But it is also true that newcomers have a lot of problems trying to use raw binaries, and it's probably a good idea to start out using a more versatile format.

I'm afraid that your post is the most hostile one here.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: How do I mix C with x86 assembly language?

Post by Schol-R-LEA »

OK, I will leave that topic alone and proceed.

@stevewoods1986, if you are still reading this: can you describe what your plan of attack on this is a bit more, please?

While NASM (and FASM, I think - EDIT: yes, it does; you can use the format binary and use16 assembler directives together to get a real mode executable image) is perfectly capable of producing a binary image from a single assembly source (which could have includes of other NASM source files in it, I suppose), such an image cannot be then linked - not by any tool I am aware of. You need to have them in a linkable object format in order to build the executable from separate Object Files, regardless of the final target.

There really isn't any other way to do this with most toolchains - it is not specifically a GCC/GAS or NASM issue.

As an aside: it may be worth mentioning that it is not feasible to try to combine the boot block and the stage of the OS loaded by the boot block into a single image, even if they end up adjacent in the disk image. I don't know if this is something you are considering, but I made that mistake myself early on, and I've seen others do so as well.

The usual approach for producing a binary image from a composite program - regardless of the source code in the different parts - is to compile or assemble to a linkable format, then link them into a general relocatable executable format such as ELF or PE, then use a tool such as objdump to produce the raw image file.

As has been mentioned, if you are using ELF files under Linux (and, I think, PE files in Windows with the Cygwin or MinGW toolchain ports) you can use a linker script to tell ld to produce a binary image directly, but this would still need to be produced from one or more linkable object files. This may not be worth the trouble in this instance, as it sounds like your intent is to simply test a few aspects of things right now, but (depending on your toolchain) you will probably need to learn how to work with linker scripts at some point in order to get the fine control over the executables which you will need. Just a heads' up.

However, given that this seems to be a test, and one meant to run in real mode, using the binutils/GCC toolchain at all may present a problem, as they have only minimal support for targeting 16-bit real mode (I found this blog post discussing the topic in greater detail, if you are curious). There are a number of other C compilers that can target real mode - the previously mentioned OpenWatcom, for example, or Bruce's C Compiler (most Linux package managers will have it in their repos, and there's a short piece about using it here) - but GCC cannot.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Post Reply