assembly error: i386 architecture incompatible with i386:x86-64 output
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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!
Click here to see the post LQ members have rated as the most helpful post in this thread.
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.
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.
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....
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.
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
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.
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.
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?
Hi there.
Another option you could go with is to use the 64 bit for the loader:
nasm -f elf64 betweenA.asm -o betweenA.o
gcc -o between.out between.c betweenA.o
./between.out
This would also be acceptable if you are missing dependencies. This way you can do the conversion in NASM. I understand that you are using the g++ and i am using the gcc...so i apologize...please try it out and see if it helps (i rarely work on high level languages anymore.)
Below is the code i tested it on:
For C:
#include <stdio.h>
int main(){
printf("In C!\n"); //only use prinf this way as it is an example...using it this way is asking to be exploited
extern test_();
test_();
return 0;
}
For NASM:
section .data
msg db "In NASM!",0xA
msgL equ $-msg
section .text
global test_
test_:
mov EAX,4
mov EBX,1
mov ECX,msg
mov EDX,msgL
int 0x80
ret
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.