1

I am trying to compile an asm program on a linux server. I am new to writing asm programs, but I follow my school's tutorial and do everything they say but it has no success.

Here is my hello.asm file.

    SECTION .data
msg:    db "Hello World",10
len:    equ $-msg
    SECTION .text
        global main
main:
    mov edx,len
    mov ecx,msg
    mov ebx,1
    mov eax,4
    int 0x80
    mov ebx,0
    mov eax,1
    int 0x80

I compile this file using the command line nasm -f elf hello.asm which works completely fine and generates an object file. The problem is, when I try ld hello.o, it says that it cannot read symbols in the file and the file is in the wrong format.

Can anyone help me and tell me how I can compile a .asm file so it can run?

BigBerger
  • 1,765
  • 4
  • 23
  • 43
  • What if you link with `gcc -o hello hello.o` ? – Michael Sep 22 '14 at 15:32
  • It gives me the same error and tells me ld has a return status of 1. – BigBerger Sep 22 '14 at 15:40
  • 2
    Try: `ld -e main -m elf_i386 hello.o` or `gcc -m32 hello.o`. What do `uname -smr; dpkg --print-architecture; dpkg --print-foreign-architectures` (command in one line) say? – rkhb Sep 22 '14 at 16:12
  • Are you by any chance trying to link a elf32 object file with a 64-bit linker? In that case you can set an appropriate linker emulation by passing `-m ` to `ld` (where `` is one of the names you get when you run `ld -V`). – Michael Sep 22 '14 at 16:12

1 Answers1

2

I've had a similar problem today, as a result of mixed 32-bit and 64-bit libraries (which is why I happen to have come upon your question). ld will complain if you try to link libraries of different types. On a 64-bit system, ld defaults to 64-bit.

To specify the type you should be able to specify ld -m elf_i386 for 32-bit, or gcc -m32. (Or gcc -m32 -static -nostdlib for a static binary).

If your asm source code is portable to 64-bit, you could assemble as 64-bit with nasm -f elf64. But it can assemble but fault at runtime from truncating a pointer, or have system calls return errors instead of working because the int 0x80 ABI is purely 32-bit.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
robert
  • 4,612
  • 2
  • 29
  • 39
  • Re: your last line: x86_64 syscall numbers differ from x86. – ninjalj Oct 30 '14 at 18:57
  • thanks, I've clarified. – robert Oct 30 '14 at 18:59
  • It's `-m elf_i386` for `ld`, or `gcc -m32 -static -nostdlib` for gcc. And no, you shouldn't just build 32-bit asm source as 64-bit with `nasm -felf64`. It may fail to assemble (on `push ebx` or whatever), or fault at runtime if you use `esp`, or silently fail if you truncate 64-bit address to 32-bit by passing them to [`int 0x80` 32-bit ABI system calls](https://stackoverflow.com/questions/46087730/what-happens-if-you-use-the-32-bit-int-0x80-linux-abi-in-64-bit-code) – Peter Cordes Mar 14 '18 at 03:40
  • works for me!!! – robert Mar 14 '18 at 10:28