LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 08-21-2010, 06:01 AM   #1
rohedin
LQ Newbie
 
Registered: May 2010
Distribution: Linux Mint 8 - Gnome
Posts: 22

Rep: Reputation: 15
Question assembly error: i386 architecture incompatible with i386:x86-64 output


I was following a simple tutorial on how to program and compile a hello world program using assembly when I got this error;
Quote:
ld: i386 architecture of input file `hello.o' is incompatible with i386:x86-64 output.
The tutorial told me to make two files;
Quote:
hello.asm

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



and hello.S

.data # section declaration

msg:
.ascii "Hello, world!\n" # our dear string
len = . - msg # length of our dear string

.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

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

# and exit

movl $0,%ebx # first argument: exit code
movl $1,%eax # system call number (sys_exit)
int $0x80 # call kernel
it then told me to run the command;
Quote:
nasm -f elf hello.asm
which returned no output but generated a file, hello.o

the tutorial then asked me to compile the file with the command;
Quote:
ld -s -o hello hello.o
which generated the output;
Quote:
ld: i386 architecture of input file `hello.o' is incompatible with i386:x86-64 output
I would greatly appreciate any feed back
Thanx in advance!
 
Old 08-21-2010, 07:17 AM   #2
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,139

Rep: Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127
Quote:
Originally Posted by rohedin View Post
I was following a simple tutorial on how to program and compile a hello world program using assembly when I got this error;
You are running on a 64 bit (x86_64) system and following instructions that were written for a 32 bit (i386) system.

The asm code you used is 32 bit i386 assembler. The nasm command you gave assembles that into 32 bit elf. The ld command you gave attempts to link that into the native architecture for your machine (x86_64).

Quote:
the tutorial then asked me to compile the file with the command;
Actually, that step is linking, not compiling.

Quote:
ld -s -o hello hello.o
Instead of that use

Code:
ld -m elf_i386 -s -o hello hello.o


That command should link 32 bit (i386) code on any system whose binary tools support i386, even if i386 is not the system's native architecture.

Most x86_64 Linux distributions include enough i386 support for you to link and run that 32 program. I assume Linux Mint does, but I don't know how to be sure short of trying the above.

BTW, you didn't need the hello.s file. The hello.asm file is the complete program in nasm syntax. The hello.s file is the same complete program, but in gas syntax.

If I'm looking at the correct tutorial
http://www.tldp.org/HOWTO/html_single/Assembly-HOWTO/
It also tells you to assemble the gas version with
Code:
as -o hello.o hello.S
and link it with
Code:
ld -s -o hello hello.o
You should be aware that both those commands use the native architecture of you system (unlike the nasm command you used, which was 32 bit even on a 64 bit system).

So if you use the above as and ld commands, you are taking 32 bit source code and assembling and linking it as 64 bit binary.

For this particular trivial program, that actually works. The 64 bit program produced from 32 bit source code will do the right thing.

But if you try that with more advanced examples, it generally won't work. 32 bit source code usually needs to be assembled and linked to 32 bit binary.

Last edited by johnsfine; 08-21-2010 at 07:47 AM.
 
1 members found this post helpful.
Old 08-22-2010, 11:49 AM   #3
resetreset
Senior Member
 
Registered: Mar 2008
Location: India
Distribution: Dynebolic, Ubuntu 10.10
Posts: 1,320

Rep: Reputation: 62
John,
Could you expound a bit on how a 64-bit system handles 32-bit code? When the chip is in 64-bit mode, it can still run 32-bit code, right? ie. when there is a task switch to a 32-bit piece of code, the CPU will enter "64-bit 32-bit mode", which is different from *just* 32-bit mode as entered upon at bootup time by the chip? Which will make it interpret the actual numbers going to the chip as 32-bit opcodes, instead of 64-bit ones?
I *think* I read about this a long time back on Ars Technica, but my memory has failed me since then....


Thanks for your input.
 
Old 08-22-2010, 01:15 PM   #4
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,139

Rep: Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127
Quote:
Originally Posted by resetreset View Post
John,
Could you expound a bit on how a 64-bit system handles 32-bit code?
Not much, because there are important details I either don't recall or never really understood. But I can answer some of what you asked.

Quote:
When the chip is in 64-bit mode
Meaning when the chip is in the mode used by a 64 bit OS. I'm not that clear on exactly what the CPU can/cannot do in that mode. Some of what the CPU can do in mode of a 32 bit OS is not possible in the mode of a 64 bit OS. But ordinary flat 32 bit program mode is possible under either type OS.

Quote:
it can still run 32-bit code, right?
Right.

Quote:
ie. when there is a task switch to a 32-bit piece of code, the CPU will enter "64-bit 32-bit mode", which is different from *just* 32-bit mode
Yes.

Quote:
32-bit mode as entered upon at bootup time by the chip?
Actually the chip starts up in 16 bit "real" mode.
 
Old 12-18-2011, 01:53 PM   #5
Oksiu
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Rep: Reputation: Disabled
Hello!
I have similar problem.
When i wanna link assembly file with cpp file.
I using commands:

nasm -f elf funsumuj.asm -o funsumuj.o

ld -shared funsumuj.o -o libfunsumuj.so

g++ -c sumuj.cpp

g++ sumuj.o funsumuj.o -o sumuj

./sumuj
But it also doesn't work.
Error with i have looks that:

/usr/bin/ld: i386 architecture of input file `funsumuj.o' is incompatible with i386:x86-64 output

With commands should i use?
 
Old 12-18-2011, 02:18 PM   #6
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,139

Rep: Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127
Quote:
Originally Posted by Oksiu View Post
With commands should i use?
In an ld command, you use -m elf_i386 as I showed in my first post of this thread. You use that in addition to all the other options that you would have used if running on a system where i386 was the default architecture.

In a g++ command, you use -m32 that same way (in addition to all the other options used on an i386 system).

But your list of commands is a bit strange: You assemble funsumuj.asm into an object file, then link that into a .so, but then you link the object file (not the .so) into your final executable. So your ld command seems to be wasted.

If your original commands would have worked on a 32 bit system, the following ought to work on x86-64

nasm -f elf funsumuj.asm -o funsumuj.o
g++ -m32 -c sumuj.cpp
g++ -m32 sumuj.o funsumuj.o -o sumuj
./sumuj

If funsumuj.asm is really supposed to be used as a shared library, you would use

nasm -f elf funsumuj.asm -o funsumuj.o
ld -m elf_i386 -shared funsumuj.o -o libfunsumuj.so
g++ -m32 -c sumuj.cpp
g++ -m32 sumuj.o libfunsumuj.so -o sumuj
./sumuj

Last edited by johnsfine; 12-18-2011 at 02:27 PM.
 
Old 12-18-2011, 06:21 PM   #7
Oksiu
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Rep: Reputation: Disabled
Thank you very much.
 
Old 12-19-2011, 09:46 AM   #8
Oksiu
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Rep: Reputation: Disabled
It's still dont work.
I have error:
Code:
administrator@ubuntu:~/Dokumenty$ g++ -m32 -c 2.cpp
In file included from /usr/include/c++/4.6/x86_64-linux-gnu/32/bits/os_defines.h:40:0,
                 from /usr/include/c++/4.6/x86_64-linux-gnu/32/bits/c++config.h:392,
                 from /usr/include/c++/4.6/iostream:39,
                 from 2.cpp:1:
/usr/include/features.h:323:26: fatal error: bits/predefs.h: Nie ma takiego pliku ani katalogu
compilation terminated.
 
Old 12-19-2011, 10:20 AM   #9
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,139

Rep: Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127Reputation: 1127
I'm not using Ubuntu, nor gcc4.6 myself, so I can't easily check any of this. On the systems I have access to features.h does not try to include predefs.h

But I did a google search on your error, and the various discussions of that error that I found indicate a piece of 32-bit support is not installed on your 64-bit Ubuntu. That piece can be installed with the command

sudo apt-get install libc6-dev-i386

Note, I can't confirm that is correct. I just copied from discussion of the error message you quoted. I especially can't confirm that is the only required piece of 32bit support that you are missing. If that fixes this error, it might only advance you to some error indicating the next missing -i386 package.

Last edited by johnsfine; 12-19-2011 at 10:23 AM.
 
  


Reply

Tags
architecture, assembly, error, incompatible, ld, nasm


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] .libs/noncopyable.o' is incompatible with i386:x86-64 output TheIndependentAquarius Linux - General 11 05-05-2010 10:15 AM
Error installing ATK-1.25.2 in Fedora 9 -i386 architecture deepankar15 Linux - Software 2 04-26-2009 02:16 AM
i386 :/x86-64 architecture of input file '*.o' is incompatible with i386 output Fiona Linux - Newbie 1 05-07-2008 08:23 AM
warning: unknown architecture of input file *** incompatible with i386 output johnpaulodonnell Linux - Newbie 5 02-14-2007 05:44 PM
Architecture changed from i586 to i386 pawlub Linux - Hardware 1 03-10-2004 06:27 PM


All times are GMT -5. The time now is 05:25 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration