linux - [Solved-1 Solution] Assembling 32-bit binaries on a 64-bit system (GNU toolchain) - ubuntu - red hat - debian - linux server - linux pc
Linux - Problem :
Here write the assembly code that can be compiled:
There is on problem when you link the power.o object file:
In order to run on the 64bit OS (Ubuntu 14.04), You included .code32 at the beginning of the power.s file, however you still get error:
Segmentation fault (core dumped)
power.s:
Linux - Solution 1:
TL:DR: use gcc -m32.
- .code32 does not change the output file format, and that's what determines the mode your program will run in.
- It's up to you to not try to run 32bit code in 64bit mode.
- .code32 is for assembling "foreign" machine code that you might need as data, or to export in a shared-memory segment.
- If that's not what you're doing, avoid it so you'll get build-time errors when you build a .S in the wrong mode if it has any push or pop instructions for example.
- Use the .S extension for hand-written assembler. (gcc foo.S will run it through the C preprocessor before as, so you can #include a header with syscall numbers, for example).
- Also, it distinguishes it from .s compiler output (from gcc foo.c -O3 -S).
To build 32bit binaries, use one of these commands
- Using libc functions from _start. Some functions, like malloc(3), or stdio functions including printf(3), depend on some global data being initialized (e.g. FILE *stdout and the object it actually points to).
- gcc -nostartfiles leaves out the CRT _start boilerplate code, but still links libc (dynamically, by default).
- On Linux, shared libraries can have initializer sections that are run by the dynamic linker when it loads them, before jumping to your _start entry point.
- So gcc -nostartfiles hello.S still lets you call printf.
- For a dynamic executable, the kernel runs /lib/ld-linux.so.2 on it instead of running it directly (use readelf -a to see the "ELF interpreter" string in your binary).
- When your _start eventually runs, not all the registers will be zeroed, because the dynamic linker ran code in your process.
- However, gcc -nostartfiles -static hello.S will link, but crash at runtime if you call printf or something without calling glibc's internal init functions.
- Of course you can put any combination of .c, .S, and .o files on the same command line to link them all into one executable. If you have any C, don't forget -Og -Wall -Wextra: you don't want to be debugging your asm when the problem was something simple in the C that calls it that the compiler could have warned you about.
- Use -v to have gcc show you the commands it runs to assemble and link. To do it "manually":
gcc -nostdlib -m32 is easier to remember and type than the two different options for as and ld (--32 and -m elf_i386). Also, it works on all platforms, including ones where executable format isn't ELF.