How to generate assembly code with gcc that can be compiled with nasm

The difficulty I think you hit with the entry point error was attempting to use ld on an object file containing the entry point named main while ld was looking for an entry point named _start.

There are a couple of considerations. First, if you are linking with the C library for the use of functions like printf, linking will expect main as the entry point, but if you are not linking with the C library, ld will expect _start. Your script is very close, but you will need some way to differentiate which entry point you need to fully automate the process for any source file.

For example, the following is a conversion using your approach of a source file including printf. It was converted to nasm using objconv as follows:

Generate the object file:

gcc -fno-asynchronous-unwind-tables -s -c struct_offsetof.c -o s3.obj

Convert with objconv to nasm format assembly file

objconv -fnasm s3.obj

(note: my version of objconv added DOS line endings -- probably an option missed, I just ran it through dos2unix)

Using a slightly modified version of your sed call, tweak the contents:

sed -i -e 's/align=1//g' -e 's/[a-z]*execute//g' -e \
's/: *function//g' -e '/default *rel/d' s3.asm

(note: if no standard library functions, and using ld, change main to _start by adding the following expressions to your sed call)

-e 's/^main/_start/' -e 's/[ ]main[ ]*.*$/ _start/'

(there are probably more elegant expressions for this, this was just for example)

Compile with nasm (replacing original object file):

nasm -felf64 -o s3.obj s3.asm

Using gcc for link:

gcc -o s3 s3.obj

Test

$ ./s3

 sizeof test : 40

 myint  : 0  0
 mychar : 4  4
 myptr  : 8  8
 myarr  : 16  16
 myuint : 32  32

You basically can't, at least directly. GCC does output assembly in Intel syntax; but NASM/MASM/TASM have their own Intel syntax. They are largely based on it, but there are as well some differences the assembler may not be able to understand and thus fail to compile.

The closest thing is probably having objdump show the assembly in Intel format:

objdump -d $file -M intel

Peter Cordes suggests in the comments that assembler directives will still target GAS, so they won't be recognized by NASM for example. They typically have the same name, but GAS-like directives start with a . as in .section text (vs section text).

Tags:

Gcc

Assembly

Nasm