Il problema riguarda Ubuntu per Windows (sottosistema Windows per Linux). Supporta solo syscall
a 64 bit interfaccia e non il int 0x80
x86 a 32 bit meccanismo di chiamata di sistema.
Oltre a non poter usare int 0x80
(compatibilità a 32 bit) nei file binari a 64 bit, Ubuntu su Windows (WSL) non supporta nemmeno l'esecuzione di eseguibili a 32 bit.
Devi convertire usando int 0x80
a syscall
. Non è difficile. Per un syscall
viene utilizzato un insieme diverso di registri e i numeri di chiamata di sistema sono diversi dalle loro controparti a 32 bit. Il blog di Ryan Chapman contiene informazioni sul syscall
interfaccia, le chiamate di sistema e i relativi parametri. Sys_write
e Sys_exit
sono definiti in questo modo:
%rax System call %rdi %rsi %rdx %r10 %r8 %r9 ---------------------------------------------------------------------------------- 0 sys_read unsigned int fd char *buf size_t count 1 sys_write unsigned int fd const char *buf size_t count 60 sys_exit int error_code
Usando syscall
distrugge anche RCX e R11 registri. Sono considerati volatili. Non fare affidamento sul fatto che abbiano lo stesso valore dopo syscall
.
Il tuo codice potrebbe essere modificato in:
section .text
global _start ;must be declared for linker (ld)
_start: ;tells linker entry point
mov edx,len ;message length
mov rsi,msg ;message to write
mov edi,1 ;file descriptor (stdout)
mov eax,edi ;system call number (sys_write)
syscall ;call kernel
xor edi, edi ;Return value = 0
mov eax,60 ;system call number (sys_exit)
syscall ;call kernel
section .data
msg db 'Hello, world!', 0xa ;string to be printed
len equ $ - msg ;length of the string
Nota:nel codice a 64 bit se la destinazione registro di un'istruzione è a 32 bit (come EAX , EBX , EDI , ESI ecc.) lo zero del processore estende il risultato nei 32 bit superiori del registro a 64 bit. mov edi,1
ha lo stesso effetto di mov rdi,1
.
Questa risposta non è un'introduzione alla scrittura di codice a 64 bit, ma solo all'utilizzo del syscall
interfaccia. Se sei interessato alle sfumature della scrittura del codice che richiama la C libreria e conforme all'ABI System V a 64 bit, ci sono tutorial ragionevoli per iniziare come il tutorial NASM di Ray Toal. Discute l'allineamento dello stack, la zona rossa, l'utilizzo del registro e una panoramica di base della convenzione di chiamata di System V a 64 bit.
Come già sottolineato nei commenti di Ross Ridge, non usare chiamate a 32 bit delle funzioni del kernel quando compili a 64 bit.
Compilare per 32 bit o "tradurre" il codice in chiamate di sistema a 64 bit. Ecco come potrebbe essere:
section .text
global _start ;must be declared for linker (ld)
_start: ;tells linker entry point
mov rdx,len ;message length
mov rsi,msg ;message to write
mov rdi,1 ;file descriptor (stdout)
mov rax,1 ;system call number (sys_write)
syscall ;call kernel
mov rax,60 ;system call number (sys_exit)
mov rdi,0 ;add this to output error code 0(to indicate program terminated without errors)
syscall ;call kernel
section .data
msg db 'Hello, world!', 0xa ;string to be printed
len equ $ - msg ;length of the string