15

I have program written in 32 bit assembly language... Now I just can't compile it on 64 bit OS. On our school they are specific and program has to be written in 32 bit version. Here is my program:

bits 32
extern _printf
global _start

section .data
    message db "Hello world!!", 10, 0

section .text

_start:
    pushad 
    push dword message
    call _printf 
    add esp, 4 
    popad 
    ret

Any idea? I have tried so many ways to compile that. Error output after compiling:

nasm -f elf64 vaja4.asm
ld vaja4.o -o vaja4
./vaja4

output:

vaja4.o: In function `_start':
vaja4.asm:(.text+0x7): undefined reference to `_printf'
Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
Klemenko
  • 704
  • 1
  • 10
  • 21

4 Answers4

24

First change _printf to printf and the _start symbol to main, then use gcc to link the object file, which will automatically link it to libc, you need to do that because AFAIK you can't link to libc without a main. Also you should use elf32 not elf64 when assembling because the code has 32 bits instructions :

bits 32
extern printf
global main

section .data
    message db "Hello world!!", 10, 0

section .text

main:
    pushad 
    push dword message
    call printf 
    add esp, 4 
    popad 
    ret

And build with:

nasm -f elf32 vaja4.asm
gcc -m32 vaja4.o -o vaja4
$./test 
$Hello world!!

Edit:

Since you're now compiling 32-bit code on a 64-bit system, you will need to install the 32-bit version of the libraries

apt-get install ia32-libs 
rustyMagnet
  • 3,479
  • 1
  • 31
  • 41
iabdalkader
  • 17,009
  • 4
  • 47
  • 74
  • 1
    Yes, this is the right way. If you want to use libc you should use `main` as entry point and link using gcc so that the proper pieces of libc are pulled in and the initialization/shutdown are taken care of. Also, simply returning only works from `main`, if you create a binary without libc you must use an exit system call. – Jester Nov 01 '12 at 14:34
  • Well I tried your way. After gcc -m32 vaja4.o -o vaja4 it gives me that error output: http://pastebin.com/jX3N2GSJ – Klemenko Nov 01 '12 at 14:39
  • you need to install the 32-bits libraries apt-get install ia32-libs – iabdalkader Nov 01 '12 at 14:44
  • 1
    I tried to install that libraries and still same error. Now I install libc6-dev-i386 libraries and it works! Ty :) – Klemenko Nov 01 '12 at 14:49
  • You can link libc from a program that only defines `_start`. If you make a static binary, though, you have to call glibc's init functions, or use a libc like musl that doesn't need init functions. (dynamic linking on Linux calls glibc's init functions before `_start`). See my answer on the question I marked this one a duplicate of. (The `_printf` vs. `printf` issue is separate, but otherwise it's asking the same thing) – Peter Cordes Jul 08 '16 at 17:28
9

On Ubuntu 12.10, you need to install development packages first

sudo apt-get update
sudo apt-get install libc6-dev-i386

for

gcc -m32 vaja4.o -o vaja4

to work.

Juan Antonio Gomez Moriano
  • 13,103
  • 10
  • 47
  • 65
bit_pusher
  • 158
  • 1
  • 5
4

I doubt that the error you see is because of 32/64 bit issue. The error that you see i.e

vaja4.asm:(.text+0x7): undefined reference to `_printf'

is clearly telling you the symbol _printf is undefined which means that the library for printf function is not being linked.

your linking step i.e

ld vaja4.o -o vaja4

does not include any libraries. You need to link your program with a library that can provide definition of the printf function. I believe ld should pick the library it self without bothering you with these messages but because it is not able to find a suitable C library for this function, I guess you dont have the required libraries i.e either 32 bit or 64 library is missing.

Anyway, plz try the following sequence of commands to assemble and link your program:

nasm -f elf vaja4.asm
ld -m elf_i386 vaja4.o vaja4
./vaja4
binW
  • 13,220
  • 11
  • 56
  • 69
  • Or even `ld -m elf_i386 -I/lib/ld-linux.so.2 -lc vaja4.o -o vaja4` Might not need the `-I` switch - definitely need `-lc` and `-o` on the output file name. The `_start ` label is jumped to, not called. so you can't `ret` from it. Easier to use `main` and gcc... – Frank Kotler Nov 01 '12 at 19:04
1

It looks to me like you forgot to link against the C library, which is the part that provides the printf function (and others):

ld vaja4.o -o vaja4 -lc
Nikos C.
  • 50,738
  • 9
  • 71
  • 96