Masalahnya adalah dengan Ubuntu untuk Windows (Subsistem Windows untuk Linux). Ini hanya mendukung syscall
64-bit antarmuka dan tidak x86 32-bit int 0x80
mekanisme panggilan sistem.
Selain tidak bisa menggunakan int 0x80
(kompatibilitas 32-bit) dalam binari 64-bit, Ubuntu di Windows (WSL) juga tidak mendukung menjalankan executable 32-bit.
Anda perlu mengonversi menggunakan int 0x80
ke syscall
. Itu tidak sulit. Kumpulan register yang berbeda digunakan untuk syscall
dan nomor panggilan sistem berbeda dari rekan 32-bit mereka. Blog Ryan Chapman memiliki informasi tentang syscall
antarmuka, panggilan sistem, dan parameternya. Sys_write
dan Sys_exit
didefinisikan dengan cara ini:
%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
Menggunakan syscall
juga mengalahkan RCX dan R11 register. Mereka dianggap fluktuatif. Jangan mengandalkan nilai yang sama setelah syscall
.
Kode Anda dapat dimodifikasi menjadi:
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
Catatan:dalam kode 64-bit jika tujuan daftar instruksi adalah 32-bit (seperti EAX , EBX , EDI , ESI dll) nol prosesor memperluas hasilnya ke 32-bit atas dari register 64-bit. mov edi,1
memiliki efek yang sama dengan mov rdi,1
.
Jawaban ini bukan dasar untuk menulis kode 64-bit, hanya tentang penggunaan syscall
antarmuka. Jika Anda tertarik dengan nuansa penulisan kode yang memanggil C perpustakaan, dan sesuai dengan 64-bit System V ABI ada tutorial yang masuk akal untuk Anda mulai seperti tutorial NASM Ray Toal. Dia membahas penyelarasan tumpukan, zona merah, penggunaan register, dan ikhtisar dasar konvensi pemanggilan Sistem V 64-bit.
Seperti yang telah ditunjukkan dalam komentar oleh Ross Ridge, jangan gunakan pemanggilan fungsi kernel 32-bit saat Anda mengompilasi 64bit.
Kompilasi untuk 32bit atau "terjemahkan" kode ke syscalls 64 bit. Berikut tampilannya:
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