How to compile an assembly file in a binary file format (for example, DOS.com) using the GNU assembler (as)?

I want to compile this source code on Windows (this is just an example):

start: NOP NOP 

When I compile it using nasm or fasm, the ouput file is 2 bytes long, but when I compile it using GNU (as) assembler, the ouput file is 292 bytes!

How to compile an assembly file in a raw binary file format (for example, DOS.com) using the GNU assembler (as)?


Why am I doing this?

I want to write my own OS, I write my codes using C (without using any standard C libraries even stdio.h or math.h) and converts them into an assembly:

 gcc -S my_os.c -o my_os.asm -masm=intel 

Then I compile the assembly file into the source binary:

 as my_os.asm 

Then I rename a.out (assembler output) to my_os.flp and finally launched my os using VMWare :)

+4
source share
2 answers

- forormat binary code for quick and dirty tests:

 as -o ao aS ld --oformat binary -o a.out ao hd a.out 

gives:

 00000000 90 90 |..| 00000002 

Unfortunately, this gives a warning:

 ld: warning: cannot find entry symbol _start; defaulting to 0000000000400000 

which doesn't make much sense with binary . It can be disabled:

 .section .text .globl start start: nop nop 

and

 ld -e start --oformat binary -o a.out ao 

or just using:

 ld -e 0 --oformat binary -o a.out ao 

which tells ld that the entry point is not _start , but the code at address 0 .

It is a pity that neither as nor ld can accept input / output data from stdin / stdout, so there are no pipelines.

The correct boot sector

If you are going to do something more serious, the best way is to create a clean minimal script linker. linker.ld :

 SECTIONS { . = 0x7c00; .text : { *(.*) . = 0x1FE; SHORT(0xAA55) } } 

Here we also put magic bytes with a script linker.

The script component is important primarily for managing output addresses after moving. Learn more about moving ... fooobar.com/questions/4539 / ...

Use it as:

 as -o ao aS ld --oformat binary -o a.img -T linker.ld ao 

And then you can boot as:

 qemu-system-i386 -hda a.img 

Working examples in this repository: https://github.com/cirosantilli/x86-bare-metal-examples/blob/d217b180be4220a0b4a453f31275d38e697a99e0/Makefile

Tested on Binutils 2.24, Ubuntu 14.04.

+3
source

Use NASM with the -f bin option to compile assembly code into a raw binary.

+1
source

Source: https://habr.com/ru/post/1385991/


All Articles