Error when trying to run .asm file on NASM on Ubuntu

rogcg picture rogcg · Nov 23, 2010 · Viewed 19.2k times · Source

I'm using ubuntu 64-bit and trying to run a .asm file on NASM. But it returns this error when I try to run the following code. What Iḿ trying to do is build an executable by compiling (or assembling) object file from the source $ nasm -f elf hello.asm, and then after created the file hello.o is producing executable file itself from the object file by invoking linker

$ ld -s -o hello hello.o

This will finally build hello executable.

I'm following this tutorial http://www.faqs.org/docs/Linux-HOWTO/Assembly-HOWTO.html

Error:

i386 architecture of input file `hello.o' is incompatible with i386:x86-64 output

Code:

     section .data              ;section declaration

 msg     db      "Hello, world!",0xa    ;our dear string
 len     equ     $ - msg                 ;length of our dear string

 section .text              ;section declaration

             ;we must export the entry point to the ELF linker or
     global _start       ;loader. They conventionally recognize _start as their
             ;entry point. Use ld -e foo to override the default.

 _start:

 ;write our string to stdout

         mov     edx,len ;third argument: message length
         mov     ecx,msg ;second argument: pointer to message to write
         mov     ebx,1   ;first argument: file handle (stdout)
         mov     eax,4   ;system call number (sys_write)
         int     0x80   ;call kernel

  ;and exit

     mov    ebx,0   ;first syscall argument: exit code
         mov     eax,1   ;system call number (sys_exit)
         int     0x80   ;call kernel

Answer

paxdiablo picture paxdiablo · Nov 23, 2010

This looks like it may be a simple mismatch between what's produced by nasm and what ld is trying to make:

i386 architecture of input file 'hello.o' is incompatible with i386:x86-64 output

In other words, nasm has produced a 32-bit object file hello.o and ld wants to take that and make a 64-bit executable file.

The nasm -hf command should give you the available output formats:

valid output formats for -f are (`*' denotes default):
  * bin       flat-form binary files (e.g. DOS .COM, .SYS)
    ith       Intel hex
    srec      Motorola S-records
    aout      Linux a.out object files
    aoutb     NetBSD/FreeBSD a.out object files
    coff      COFF (i386) object files (e.g. DJGPP for DOS)
    elf32     ELF32 (i386) object files (e.g. Linux)
    elf       ELF (short name for ELF32) 
    elf64     ELF64 (x86_64) object files (e.g. Linux)
    as86      Linux as86 (bin86 version 0.3) object files
    obj       MS-DOS 16-bit/32-bit OMF object files
    win32     Microsoft Win32 (i386) object files
    win64     Microsoft Win64 (x86-64) object files
    rdf       Relocatable Dynamic Object File Format v2.0
    ieee      IEEE-695 (LADsoft variant) object file format
    macho32   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
    macho     MACHO (short name for MACHO32)
    macho64   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
    dbg       Trace of all info passed to output stage

I see that your linked tutorial asks you to run:

nasm -f elf hello.asm

Try using:

nasm -f elf64 hello.asm

instead, and you may find ld stops complaining about the input file.