About the Executable and Linkable Format is a common standard file format for executable files, object code, shared libraries, and core dumps, see the Wikipedia webpage.
I used the last version 1.73.16 of flat assembler for Linux to test this format.
Even I used fasm.x64 and uses 64 the files output will in 32 bit.
1 2 | [mythcat@desk fasm]$ ls examples fasm fasm.txt fasm.x64 license.txt source tools whatsnew.txt |
A simple hello world example in assembly can be written in many ways, but today I will show how can this issue use this format.
The first file named 64_r_w_001.fasm will use the segment readable writeable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | format ELF executable 3 segment readable executable entry start start: mov eax,4 mov ebx,1 mov ecx,msg mov edx,msg_size int 0x80 mov eax,1 xor ebx,ebx int 0x80 segment readable writeable msg db 'Hello world!',0xA msg_size = $-msg |
The output will be an executable ELF file:
1 2 3 4 5 | [mythcat@desk fasm]$ ./fasm.x64 64_r_w_001.fasm flat assembler version 1.73.16 (16384 kilobytes memory, x64) 3 passes, 160 bytes. [mythcat@desk fasm]$ ./64_r_w_001 Hello world! |
The next source code from the file named 64_data_w_001.fasm comes with section ‘.data’ writeable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | format ELF section '.text' executable public _start _start: extrn writemsg mov esi,msg call writemsg mov eax,1 xor ebx,ebx int 0x80 section '.data' writeable msg db "Hello world again!",0xA,0 |
The result after run it with fasm.x64 will be this:
1 2 3 4 5 | [mythcat@desk fasm]$ ./fasm.x64 64_data_w_001.fasm flat assembler version 1.73.16 (16384 kilobytes memory, x64) 3 passes, 480 bytes. [mythcat@desk fasm]$ ls *.o 64_data_w_001.o |
The gcc tool will give errors for format file and see output of the argument -nostartfiles:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | mythcat@desk fasm]$ gcc -m32 -o 64_data_w_001 64_data_w_001.o /usr/bin/ld: cannot find crt1.o: No such file or directory /usr/bin/ld: cannot find crti.o: No such file or directory /usr/bin/ld: cannot find /lib/libgcc_s.so.1 inside / collect2: error: ld returned 1 exit status [mythcat@desk fasm]$ gcc -m64 -o 64_data_w_001 64_data_w_001.o /usr/bin/ld: 64_data_w_001.o: in function `_start': (.text+0x0): multiple definition of `_start'; /u[mythcat@desk fasm]$ file template_64.bin template_64.bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, no section header [mythcat@desk fasm]$ file 64_r_w_001 64_r_w_001: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, no section header sr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crt1.o:(.text+0x0): first defined here /usr/bin/ld: i386 architecture of input file `64_data_w_001.o' is incompatible with i386:x86-64 output /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crt1.o: in function `_start': (.text+0x24): undefined reference to `main' /usr/bin/ld: 64_data_w_001.o:(.text+0x6): undefined reference to `writemsg' collect2: error: ld returned 1 exit status [mythcat@desk fasm]$ gcc -m32 -o 64_data_w_001 64_data_w_001.o -nostartfiles /usr/bin/ld: cannot find /lib/libgcc_s.so.1 inside / collect2: error: ld returned 1 exit status [mythcat@desk fasm]$ gcc -m64 -o 64_data_w_001 64_data_w_001.o -nostartfiles /usr/bin/ld: i386 architecture of input file `64_data_w_001.o' is incompatible with i386:x86-64 output /usr/bin/ld: 64_data_w_001.o: file class ELFCLASS32 incompatible with ELFCLASS64 /usr/bin/ld: final link failed: file in wrong format collect2: error: ld returned 1 exit status |
The next step is show how a basic template can be executable using this format:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | program_base = 0x700000 org program_base use64 macro align value { rb (value-1) - ($ + value-1) mod value } file_header: db 0x7F,'ELF',1,1,1 rb file_header+0x10-$ dw 2,3 dd 1,start dd program_header-file_header,0,0 dw program_header-file_header,0x20,1,0,0,0 program_header: dd 1,0,program_base,0 dd bss-program_base,program_end-program_base,7,0x1000 msg db 'Hello world template!',0xA msg_size = $-msg start: mov eax,4 mov ebx,1 mov ecx,msg mov edx,msg_size int 0x80 mov eax,1 xor ebx,ebx int 0x80 bss: program_end: |
The result is this:
1 2 3 4 5 6 | [mythcat@desk fasm]$ ./fasm.x64 template_64.fasm flat assembler version 1.73.16 (16384 kilobytes memory, x64) 2 passes, 137 bytes. [mythcat@desk fasm]$ chmod +x template_64.bin [mythcat@desk fasm]$ ./template_64.bin Hello world template! |
Test the output files:
1 2 3 4 5 | <pre class="lang:asm decode:true " >[mythcat@desk fasm]$ file template_64.bin template_64.bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, no section header [mythcat@desk fasm]$ file 64_r_w_001 64_r_w_001: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, no section header </pre> |