Reputation: 21
I was trying to learn NASM and started from a helloworld program. The tutorial itself is 32 bit NASM on Linux.
I copy and paste the created helloworld.asm
(using int 0x80
32-bit system calls) and input the commands...
nasm -f elf helloworld.asm
ld -m elf_i386 helloworld.o -o helloworld
these two looks good but running ./helloworld
produces
-bash: ./helloworld: cannot execute binary file: Exec format error
Then I searched this error and fond this SO posting. I entered the commands of that answer:
sudo apt-get install gcc-multilib g++-multilib
after that, I installed this:
nasm -f elf64 helloworld.asm -o helloworld.o
ld -o helloworld helloworld.o -m elf_x86_64
both came from that answer and no error occurred.
Then I executed ./helloworld
and got the following error:
Segmentation fault (core dumped)
Okay, then I searched this new error as well. (Editor's note: What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code? explains the exact reason: WSL 1 doesn't support 32-bit int 0x80
system calls in 64-bit code, and it's generally not a good idea).
Most of the answer doesn't give an exact solution. The only one I got is this. It looks like I need to modify the NASM code, he says
64bit sys_exit = 60 32bit sys_exit = 1
64bit sys_write = 1 32bit sys_write = 4
and
32 bit sys_exit:
mov ebx, ERR_CODE
mov eax, sys_exit ; 1
int 80h
64 bit sys_exit:
mov rdi, ERR_CODE
mov rax, sys_exit ; 60
syscall
so I modified the original code and it became this:
The original code:
; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
SECTION .data
msg db 'Hello World!', 0Ah
SECTION .text
global _start
_start:
mov edx, 13
mov ecx, msg
mov ebx, 1
mov eax, 4
int 80h
mov ebx, 0 ; return 0 status on exit - 'No Errors'
mov eax, 1 ; invoke SYS_EXIT (kernel opcode 1)
int 80h
And the modified code:
; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
SECTION .data
msg db 'Hello World!', 0Ah
SECTION .text
global _start
_start:
mov edx, 13
mov ecx, msg
mov rdi, 1
mov rax, 1 ; SYS_write 64-bit ABI
syscall
mov rdi, 0 ; return 0 status on exit - 'No Errors'
mov rax, 60 ; invoke SYS_exit (kernel opcode 1)
syscall
After I modified the code, I input the command above again:
nasm -f elf64 helloworld.asm -o helloworld.o
ld -o helloworld helloworld.o -m elf_x86_64
./helloworld
Good. There is no error anymore. But there is not output either, which should be "helloworld".
Then I back to first tried the command given in tutorial, to build a 32-bit executable from the source that worked in 64-bit mode:
nasm -f elf helloworld.asm
and its result is:
helloworld.asm:16: error: instruction not supported in 32-bit mode
helloworld.asm:17: error: instruction not supported in 32-bit mode
helloworld.asm:20: error: instruction not supported in 32-bit mode
helloworld.asm:21: error: instruction not supported in 32-bit mode
Then I searched this error again, but I cannot find a solution.
My machine is a 64bit Linux Ubuntu as a Windows-Subsystem-For-Linux in 64bit Windows 10.
How to run this helloworld program correctly?
Does this mean that a 32bit Linux NASM tutorial/program just cannot run on a 64bit Linux?
Or a 64-bit Windows10?
Or in a Windows-Subsystem-For-Linux?
What is the problem, and why do occur so many errors?
How should I avoid similar potential errors in the future?
Upvotes: 2
Views: 1318
Reputation: 94
QUICK FIX
Do you want compile for 32 bits or 64 bits?
Your program will work and show output by changing only the register ecx by rsi
; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
SECTION .data
msg db 'Hello World!',0Ah
SECTION .text
global _start
_start:
mov edx, 13
mov rsi, msg
mov rdi, 1
mov rax, 1
syscall
mov rdi, 0 ; return 0 status on exit - 'No Errors'
mov rax, 60 ; invoke SYS_EXIT (kernel opcode 1)
syscall
Compile your program for 64 bits using nasm and ld
nasm -f elf64 helloworld.asm -o helloworld.o
ld helloworld.o -o helloworld.elf
Upvotes: 1