GNU/Linux >> Tutoriales Linux >  >> Linux

Qué registros se conservan a través de una llamada de función linux x86-64

Aquí está la tabla completa de registros y su uso de la documentación [Enlace PDF]:

r12 , r13 , r14 , r15 , rbx , rsp , rbp son los registros guardados por la persona que llama:tienen un "Sí" en la columna "Conservados en las llamadas a funciones".


Enfoque experimental:desensamblar el código GCC

Principalmente por diversión, pero también como una verificación rápida de que entendiste bien el ABI.

Intentemos eliminar todos los registros con el ensamblado en línea para obligar a GCC a guardarlos y restaurarlos:

principal.c

#include <inttypes.h>

uint64_t inc(uint64_t i) {
    __asm__ __volatile__(
        ""
        : "+m" (i)
        :
        : "rax",
          "rbx",
          "rcx",
          "rdx",
          "rsi",
          "rdi",
          "rbp",
          "rsp",
          "r8",
          "r9",
          "r10",
          "r11",
          "r12",
          "r13",
          "r14",
          "r15",
          "ymm0",
          "ymm1",
          "ymm2",
          "ymm3",
          "ymm4",
          "ymm5",
          "ymm6",
          "ymm7",
          "ymm8",
          "ymm9",
          "ymm10",
          "ymm11",
          "ymm12",
          "ymm13",
          "ymm14",
          "ymm15"
    );
    return i + 1;
}

int main(int argc, char **argv) {
    (void)argv;
    return inc(argc);
}

GitHub ascendente.

Compilar y desensamblar:

 gcc -std=gnu99 -O3 -ggdb3 -Wall -Wextra -pedantic -o main.out main.c
 objdump -d main.out

El desmontaje contiene:

00000000000011a0 <inc>:
    11a0:       55                      push   %rbp
    11a1:       48 89 e5                mov    %rsp,%rbp
    11a4:       41 57                   push   %r15
    11a6:       41 56                   push   %r14
    11a8:       41 55                   push   %r13
    11aa:       41 54                   push   %r12
    11ac:       53                      push   %rbx
    11ad:       48 83 ec 08             sub    $0x8,%rsp
    11b1:       48 89 7d d0             mov    %rdi,-0x30(%rbp)
    11b5:       48 8b 45 d0             mov    -0x30(%rbp),%rax
    11b9:       48 8d 65 d8             lea    -0x28(%rbp),%rsp
    11bd:       5b                      pop    %rbx
    11be:       41 5c                   pop    %r12
    11c0:       48 83 c0 01             add    $0x1,%rax
    11c4:       41 5d                   pop    %r13
    11c6:       41 5e                   pop    %r14
    11c8:       41 5f                   pop    %r15
    11ca:       5d                      pop    %rbp
    11cb:       c3                      retq   
    11cc:       0f 1f 40 00             nopl   0x0(%rax)

y entonces vemos claramente que lo siguiente se presiona y se abre:

rbx
r12
r13
r14
r15
rbp

El único que falta en la especificación es rsp , pero esperamos que la pila se restaure, por supuesto. Una lectura atenta del montaje confirma que se mantiene en este caso:

  • sub $0x8, %rsp :asigna 8 bytes en la pila para guardar %rdi en %rdi, -0x30(%rbp) , que se realiza para el ensamblado en línea +m restricción
  • lea -0x28(%rbp), %rsp restaura %rsp volver a antes del sub , es decir, 5 pops después de mov %rsp, %rbp
  • hay 6 pulsaciones y 6 pops correspondientes
  • ninguna otra instrucción toca %rsp

Probado en Ubuntu 18.10, GCC 8.2.0.


Linux
  1. ¿Cuáles son los diferentes tipos de shells en Linux?

  2. UNIX/Linux:¿Qué es un shell? ¿Cuáles son las diferentes conchas?

  3. ¿Qué son los tipos de servidores de nombres DNS en Linux?

  4. ¿Cuáles son estos procesos de Windows en Linux?

  5. ¿Qué son la memoria alta y la memoria baja en Linux?

¿Qué son los puertos? ¿Cómo verificar los puertos abiertos de Linux?

Cómo encontrar qué direcciones IP están conectadas a Linux

¿Qué son los inodos en Linux?

¿Cuáles son las convenciones de llamada para las llamadas del sistema UNIX y Linux (y funciones de espacio de usuario) en i386 y x86-64?

Qué registros se conservan a través de una llamada de función linux x86-64

¿Qué aplicaciones de edición de video están disponibles en Linux?