3

I have some confusion with two command line options of GNU linker --- ld. But before my question, I will show you some backgrounds.

I am reading Richard Blum's Professional Assembly Language these days, and cpuid.s is an sample of assembly code from this book. This book introduces 32-bit assembly programming, but mine is a 64-bit OS.

In order to generate the 32-bit output, just in accord with the book's sample. I uses the following two command to assembly and link the code:

as --32 -o cpuid.o cpuid.s
ld --oformat=elf32-i386 -o cpuid cpuid.o

however, at the second step, ld fails with "ld: i386 architecture of input file `cpuid2.o' is incompatible with i386:x86-64 output".

After some google, I find that I need to use -melf_i386 option:

ld -melf_i386 -o cpuid cpuid.o

Yeah, this time the link is success, but I don't know why, in the GNU's official documentation, it says:

you can use the `--oformat' option to specify the binary format for the output object

I uses an 32-bit object file cpuid.o, and tell ld to generate 32-bit output explicitly through --oformat=elf32-i386 optoin, I think it should be no trouble. But why must I use the -melf_i386 option? So what the reasons of existing --oformat?

I tried to googled the anwser, but failed, I found two most relevant links below, but not answers my question:

http://www.linuxquestions.org/questions/linux-software-2/relocatable-linking-on-x86-64-for-i386-872812/

Building a 32-bit app in 64-bit Ubuntu

Any help will be appreciated. Thanks...

Community
  • 1
  • 1
cifer
  • 615
  • 1
  • 9
  • 25

2 Answers2

2

An output format does not necessarily correspond to an architecture, even though that might be the case for elf32-i386. But for others like ihex or bin there is no way for ld to choose the appropriate architecture emulation. That's why it just defaults to the one it has been compiled for, which seems to be x86-64 in your case.

lnvd
  • 137
  • 2
2
as --32

means you are targeting a 32-bit arch machine but

ld --oformat=elf32-i386

means you are asking ld to make exe file format as elf in 32-bit for i386 platform, whereas -melf_i386 is asking linker to generate/emulate object file for i386 machine. So --oformat is asking linker to generate object as per target arch whereas -m is asking linker to emulate the target arch.

danish
  • 359
  • 1
  • 8