Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

388
Vistas
Llamar código ensamblador desde C++

Estoy tratando de escribir mi propia biblioteca de E/S, por lo que el primer paso es poder generar un carácter. Hasta ahora, esto solo necesita funcionar en Linux. Escribí lo que creo que es una etiqueta sólida _putc: en x86 (con sintaxis Intel), y la puse en "io.h", luego la llamé desde mi archivo principal, "test.cpp". Aquí está el contenido de test.cpp:

 #include "io.h" extern void _putc(char) __asm__("_putc"); int main(int argc, char** argv){ _putc('c'); return 0; }

y aquí está mi io.h:

 asm( "\n.intel_syntax noprefix" "\n.globl _putc" "\n_putc:" "\n\tpush [ebp]" "\n\tmov ebp,esp" "\n\tmov eax,4" "\n\tmov ebx,0" "\n\tmov ecx,[ebp+8]" "\n\tmov edx,1" "\n\tint 0x80" "\n\tret" "\n.att_syntax" ;return to g++'s at&t syntax );

Estoy desarrollando esto en un sistema operativo Linux x86_64 usando G++

Estoy usando esto para compilar:

 g++ -o test test.cpp -Wall

Cuando se ejecuta segfaults inmediatamente. Creo que mi problema es llamar a la convención, pero no hay forma de estar absolutamente seguro. Intenté envolver el ensamblaje en una función ( void _putc(char c) ) y eliminar la etiqueta global, pero eso no ayudó. También intenté empujar el contenido de ebp en lugar de las cosas a las que apunta, pero luego no se compilaría.

NOTA: Esto tiene que funcionar solo con la línea #include io.h en el archivo principal (puedo mover el extern void _putc(char) __asm__("_putc"); después de que esto funcione), y tiene que funcionar con C++ , no solo C. Además, no me den lecciones sobre las definiciones de funciones en un archivo de encabezado, eso es justo lo que estoy haciendo.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Con el código de 64 bits, realmente debe considerar usar syscall en lugar de int 0x80 . La llamada al sistema utiliza una convención de 64 bits y los números de llamada al sistema difieren de int 0x80 en código de 32 bits. Puede hacerse una idea de las llamadas al sistema de 64 bits en esta tabla . Las llamadas sys_write y sys_read se ven así:

 %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

Debe familiarizarse con System V 64-Linux ABI si desea comprender cómo se pasan los parámetros en el código Linux de 64 bits. Entre otras cosas, después de ingresar una llamada, generalmente debe alinear la pila con un límite de 16 bytes si tiene la intención de llamar a otras funciones o llamadas al sistema.

Su código también sufre una falla en la que pasa un carácter a sys_write . sys_write requiere una dirección para un búfer que contiene el carácter, no el carácter en sí.

Este es un volcado de código que funcionaría:

 asm( "\n.intel_syntax noprefix" "\n.globl _putc" "\n_putc:" "\n\tadd rsp, -8" // Allocate space on the stack to store the character passed // Also aligns stack back to 16-bye boundary // with return address already on stack "\n\tmov [rsp],rdi" // Move the character passed in RDI to memory(stack) for sys_write "\n\tmov eax,1" // With 64-bit syscalls RAX = 1 for sys_write "\n\txor edi,edi" // 1st parameter to syscall is in RDX. FD = 0 "\n\tlea rsi,[rsp]" // We need to pass pointer to memory containing our char "\n\tmov edx,1" // RDX = 1 character to print. Could reuse EAX instead of 1 for src "\n\tsyscall" // Make syscall (using syscall instead of int 0x80 for 64-bit) "\n\tadd rsp, 8" // Restore stack to state right after function entry "\n\tret" "\n.att_syntax prefix" //return to g++'s at&t syntax );
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda