stary
stary

Reputation: 21

32-bit system calls or executables on 64bit Windows Subsystem For Linux? Or a working 64-bit Hello World?

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

Answers (1)

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

Related Questions