Page 1 of 1

[SOLVED] Producing raw binary with GNU Assembler

Posted: Sun Jul 21, 2013 12:19 pm
by Vaclav
Hello,
I have made the steps in babystep 2 tutorial and it worked fine (the first code on the page, it prints a string to the screen with BIOS). Now I would like to do the same thing with the GNU Assembler, as part of GCC.
First I have built an i586-elf GCC cross compiler for my system. (Could not build libgcc too but that is not neccessary yet.)
Then I have changed the syntax to GAS syntax (not that hard).
After that I assemble it:
i586-elf-gcc -c boot.s -o boot
But this gets an elf format, so I strip it to be only the binary:
objcopy -O binary boot boot.bin
This binary does not work, when I try it, it prints 3 characters (junk) they do not change if I change the string to be printed.
Now if I compare this binary with the one got from NASM, the only difference is that two 0x66 bytes are inserted in the one assembled with GAS.
Are those some unneccesary symbols left inside? How can I fix it either with generating the binary directly with gcc, or with some extra option with objcopy? The problem is NOT with the GAS syntax assembly code, because I have tried producing elf format with NASM and stripping that too with objcopy, and it ended up with the two 0x66 bytes as well.
I have also tried

Code: Select all

as yadda.s -o yadda.o
ld yadda.o -o yadda --oformat=binary
or:
gcc yadda.s -o yadda -Xlinker --oformat=binary
Neither worked.
Here are the two hex files:
The one assembled with NASM:

Code: Select all

00000000  b8 c0 07 8e d8 be 15 00  ac 08 c0 74 06 b4 0e cd  |...........t....|
00000010  10 eb f5 eb fe 57 65 6c  63 6f 6d 65 20 74 6f 20  |.....Welcome to |
00000020  4d 61 63 69 6e 74 6f 73  68 0d 0a 00 00 00 00 00  |Macintosh.......|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200
And GAS:

Code: Select all

00000000  66 b8 c0 07 8e d8 66 be  17 00 ac 08 c0 74 06 b4  |f.....f......t..|
00000010  0e cd 10 eb f5 eb fe 57  65 6c 63 6f 6d 65 20 74  |.......Welcome t|
00000020  6f 20 4d 61 63 69 6e 74  6f 73 68 0d 0a 00 00 00  |o Macintosh.....|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200
(The 0x17 <-> 0x15 byte difference is because it is a jump address. The adress is incremented by 2 because of the two inserted 0x66 bytes.)
Thank you for your help.

Re: Producing raw binary with GNU Assembler

Posted: Sun Jul 21, 2013 12:48 pm
by Minoto
It sounds like you're producing 32-bit code (probably by default in gas, and by specifying ELF output in nasm), causing both assemblers to add the 0x66 prefix to instructions referencing 16-bit data. Look up how to produce 16-bit code in gas and see if that solves your problem.

Re: Producing raw binary with GNU Assembler

Posted: Sun Jul 21, 2013 1:26 pm
by Vaclav
Yes that was the problem, I did not think of this.
Putting .code16 at the beginning of the assembly file solved the problem. (If you changed to protected mode and you need 32 bit adresses, write .code32 to switch back, I have found it here.)
Thank you for fast and accurate reply.

Should I add this GAS way to the babystep 1 on the wiki?

Re: [SOLVED] Producing raw binary with GNU Assembler

Posted: Sun Jul 21, 2013 1:48 pm
by Nessphoro
I would argue against it.
Intel syntax is considered to be the standard due to it being present in almost all tutorials and manuals. Therefore, it is encouraged that new comers learn it first.

What you could do is perhaps make a page "Babysteps in GAS"?