"Illegal instruction" on the basic build program - don't even greet the world - why the link?

I just figured it out, but instead of splitting my new question ("why?") Into another question, I find it best if the solution to this problem and the explanation should be kept on the same page.

I am writing a basic build program to start and immediately stop using the kernel interrupt in int 0x80

. My current code looks like this:

/* Simple exit via kern-interrupt */

.globl start

    pushl $0x0
    movl $0x1, %eax
    subl $4, %esp
    int $0x80


assembled with

as -arch i386 <file>.s


on execution I get a one line error:

Illegal instruction


This bizzare, even commenting on everything, still results in Illegal instruction

, despite the lack of instructions. Did I skip a step linking

despite no other files to link? Yes I

EDIT: Let me rephrase my question, why would you need to link when there is no library or anything to link to?


source to share

2 answers

You need to link it to create an executable. The default as

just gives you an object file that can be linked to an executable (either other object files or on its own), but is not itself a valid executable. Try:

as -arch i386 -o file.o file.s
ld -o file file.o


In response to your question:

Why would you need to link when there is no library or anything to link to?

As the assembler doesn't know you are not going to mess with something else.

Unlike the compiler gcc

, which assumes you want the program, unless otherwise specified (with an option -c

), it as

provides you with a default object file. From the manpage:


intended primarily for assembling the output of the GNU C compiler "gcc"

for use by the linker"ld"

If you need a one-step command, you can create a script like asld


as -arch i386 -o $1.o $1.s
ld -o $1 $1.o


and then just use asld file


Or, you can tweak the makefiles to do the heavy lifting for you.



You can make the same argument about the C program, I am not using any libraries, why do I need to reference.

Because that's how the toolchain was designed. One set of tools takes you out of source code (any / many languages) into object files, which are incomplete in most cases. The link level, even if, as paxdiablo shows, only requires your object file and makes it executable. Unless nothing else requires your .text address (usually) and that comes from the linker stage.

It makes sense to do it this way, the linking stage is quite complex as it is, to make this tool that does the job and does the job well. Do your system design and define an interface to this tool. The language tools have a tricky job to get them to just do the job, and the output is an object file, which as far as they can decide cannot become a linker.

If you don't want to use that toolchain and maybe use nasm or something like that where you can go directly from build to binary in one command line step.



All Articles