GNU/Linux >> Linux Esercitazione >  >> Linux

L'eseguibile compilato in assembly utilizzando INT 0x80 su Ubuntu su Windows Subsystem per Linux non produce output

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

Linux
  1. Spiegazione del sottosistema Windows per Linux, WSL e WSL2

  2. Limitazione dell'accesso alle chiamate di sistema per un'applicazione Linux

  3. Installazione di Oracle JDK su sottosistema Windows per Linux

  4. Problemi con l'impostazione di $PATH su Bash su Ubuntu su Windows (sottosistema Linux)

  5. Errore Wget bash Sottosistema Windows per Linux

Come installare il sottosistema Windows per Linux

La guida definitiva al sottosistema Windows per Linux (Windows WSL)

Utilizzo della modalità avanzata Ubuntu 18.04 per Hyper-V su Windows 10

Costruire 0verkill sul sottosistema Windows 10 per Linux - Gioco deathmatch artistico 2D ASCII

Scrittura e debug di applicazioni C++ Linux da Visual Studio usando il sottosistema Windows per Linux

Come installare e configurare il sottosistema Windows per Linux