GNU/Linux >> Tutoriales Linux >  >> Linux

El ejecutable compilado de ensamblado usando INT 0x80 en Ubuntu en el subsistema de Windows para Linux no produce salida

El problema es con Ubuntu para Windows (Subsistema de Windows para Linux). Solo es compatible con syscall de 64 bits interfaz y no x86 de 32 bits int 0x80 mecanismo de llamada al sistema.

Además de no poder usar int 0x80 (compatibilidad de 32 bits) en binarios de 64 bits, Ubuntu en Windows (WSL) tampoco admite la ejecución de ejecutables de 32 bits.

Necesitas convertir usando int 0x80 a syscall . No es dificil. Se utiliza un conjunto diferente de registros para un syscall y los números de llamada del sistema son diferentes de sus contrapartes de 32 bits. El blog de Ryan Chapman tiene información sobre el syscall interfaz, las llamadas al sistema y sus parámetros. Sys_write y Sys_exit se definen de esta manera:

%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 también golpea RCX y el R11 registros Se consideran volátiles. No confíe en que tengan el mismo valor después del syscall .

Su código podría modificarse para ser:

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:en código de 64 bits si el destino registro de una instrucción es de 32 bits (como EAX , EBX , EDI , ESI etc.) el procesador cero extiende el resultado a los 32 bits superiores del registro de 64 bits. mov edi,1 tiene el mismo efecto que mov rdi,1 .

Esta respuesta no es una introducción a la escritura de código de 64 bits, solo sobre el uso de syscall interfaz. Si está interesado en los matices de escribir código que llame a la C biblioteca, y se ajusta a la ABI del Sistema V de 64 bits, hay tutoriales razonables para que pueda comenzar, como el tutorial NASM de Ray Toal. Habla sobre la alineación de la pila, la zona roja, el uso de registros y una descripción general básica de la convención de llamadas System V de 64 bits.


Como ya se señaló en los comentarios de Ross Ridge, no utilice llamadas de 32 bits a las funciones del núcleo cuando compile 64 bits.

Compile para 32 bits o "traduzca" el código a llamadas al sistema de 64 bits. Así es como podría verse:

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. ¿Qué es mejor int 0x80 o syscall en código de 32 bits en Linux?

  2. Instalación de Oracle JDK en el subsistema de Windows para Linux

  3. Uso del subsistema de Windows para Linux (WSL) de Sublime Text

  4. Montar un recurso compartido de Windows en el Subsistema de Windows para Linux

  5. Wget error bash subsistema de Windows para Linux

Cómo instalar el subsistema de Windows para Linux

La guía definitiva del subsistema de Windows para Linux (Windows WSL)

Uso del modo mejorado Ubuntu 18.04 para Hyper-V en Windows 10

Construyendo 0verkill en el subsistema de Windows 10 para Linux:juego de combate a muerte con arte ASCII en 2D

Escritura y depuración de aplicaciones C++ de Linux desde Visual Studio mediante el subsistema de Windows para Linux

Cómo instalar y configurar el subsistema de Windows para Linux