LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   assembly error: i386 architecture incompatible with i386:x86-64 output (https://www.linuxquestions.org/questions/programming-9/assembly-error-i386-architecture-incompatible-with-i386-x86-64-output-827609/)

rohedin 08-21-2010 05:01 AM

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!

johnsfine 08-21-2010 06:17 AM

Quote:

Originally Posted by rohedin (Post 4073170)
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.

resetreset 08-22-2010 10:49 AM

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.

johnsfine 08-22-2010 12:15 PM

Quote:

Originally Posted by resetreset (Post 4074189)
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.

Oksiu 12-18-2011 12:53 PM

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?

johnsfine 12-18-2011 01:18 PM

Quote:

Originally Posted by Oksiu (Post 4553069)
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

Oksiu 12-18-2011 05:21 PM

Thank you very much.

Oksiu 12-19-2011 08:46 AM

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.


johnsfine 12-19-2011 09:20 AM

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.

Nilonahs 08-11-2015 02:53 AM

Quote
 
Quote:

Originally Posted by Oksiu (Post 4553069)
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

I hope this helps... :)

NevemTeve 08-11-2015 03:54 AM

Whenever you post code into dead topics, please use [code] and [/code] tags.

Nilonahs 08-11-2015 08:13 AM

Understood.

Regards,
Nilo


All times are GMT -5. The time now is 01:37 PM.