-1

Today, I have decided to make a (very) simple OS. I don't feel like using assembly directly because I think that it is simply too messy for me. But, I know a little C, and I am eager to learn it more. I made a simple program to print a string and I want to compile it to assembly. I used this command to compile into assembly:

gcc -S foo.c

Here is my C code:

#include<stdio.h>

int main() {
        printf("Hi!!!");
}

But when I try to run the output file (foo.s), I get these errors:

foo.s:1: error: parser: instruction expected
foo.s:2: warning: label alone on a line without a colon might be in error [-w+label-orphan]
foo.s:3: error: parser: instruction expected
foo.s:5: error: parser: instruction expected
foo.s:6: warning: label alone on a line without a colon might be in error [-w+label-orphan]
foo.s:7: error: parser: instruction expected
foo.s:8: error: parser: instruction expected
foo.s:11: warning: label alone on a line without a colon might be in error [-w+label-orphan]
foo.s:12: error: parser: instruction expected
foo.s:13: error: parser: instruction expected
foo.s:14: error: parser: instruction expected
foo.s:15: error: expression syntax error
foo.s:16: error: parser: instruction expected
foo.s:17: error: parser: instruction expected
foo.s:18: error: parser: instruction expected
foo.s:20: error: label `movl' inconsistently redefined
foo.s:18: info: label `movl' originally defined here
foo.s:20: error: parser: instruction expected
foo.s:21: error: parser: instruction expected
foo.s:22: error: parser: instruction expected
foo.s:24: warning: label alone on a line without a colon might be in error [-w+label-orphan]
foo.s:26: error: parser: instruction expected
foo.s:27: error: parser: instruction expected
foo.s:28: error: parser: instruction expected

This is the command I ran to compile the assembly code:

nasm -f bin -o foo.bin foo.s

This is the assembly code in foo.s:

        .file   "foo.c"
        .text
        .section        .rodata
.LC0:
        .string "Hi!!!"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        leaq    .LC0(%rip), %rdi
        movl    $0, %eax
        call    printf@PLT
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (Debian 10.2.1-6) 10.2.1 20210110"
        .section        .note.GNU-stack,"",@progbits

Someone please help me!

1 Answers1

5

gcc output does not use NASM syntax. You should use as to assemble it into an object file, and then link with the standard library:

> as -o foo.o foo.s
> gcc foo.o # Link
> ./a.out
Hi!!!
DYZ
  • 55,249
  • 10
  • 64
  • 93
  • 2
    Thank you!!!!!!!!! I finally figured out how to compile assembly created from gcc to .bin file!!!!! – Saish Shankar Jan 11 '22 at 22:15
  • 2
    `as`'s output isn't a flat binary so `.bin` is a misleading extension for it; use `as -o foo.o` not `as -o foo.bin`. – Peter Cordes Jan 11 '22 at 23:12
  • @PeterCordes I used the same names as the OP to avoid confusion. – DYZ Jan 11 '22 at 23:15
  • 2
    That actually increases confusion because `nasm -fbin` *does* make a flat binary; GAS doesn't have a mode like that. You'd need `ld` and/or `objcopy` to make one with the GNU toolchain: [Writing / linking a flat binary using NASM + LD](https://stackoverflow.com/q/5979672) was the first google hit. Of course, you can't do that on just any executable, especially not one dynamically linked against libc, and not designed to be booted. And even if you solve that, getting sections right is tricky: [GCC create flat binary with correctly linked data section](https://stackoverflow.com/q/27065178) – Peter Cordes Jan 11 '22 at 23:18
  • So then how can I make a simple bootable program in pure C? – Saish Shankar Jan 11 '22 at 23:44
  • You should ask it as a separate question (because it is another question). – DYZ Jan 11 '22 at 23:45
  • 2
    @SaishShankar: write a UEFI application. A legacy BIOS flat binary MBR bootloader basically requires at least some asm, and is too cramped (510 bytes) to have room for a C library. Taking compiler output from a normal C program that should run under Linux and putting that machine-code + data into a flat binary is a non-starter. That will never work unless you know enough asm + inline-asm to get the C compiler to emit the right machine-code bytes, and in that case you need to know enough that you *could* have just written asm in the first place. – Peter Cordes Jan 12 '22 at 13:17