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

188
Vistas
¿Qué convención de llamadas debo usar para hacer que las cosas sean portátiles?

Estoy escribiendo una interfaz C para la instrucción cpuid de la CPU. Solo estoy haciendo esto como una especie de ejercicio: no quiero usar encabezados dependientes del compilador como cpuid.h para GCC o intrin.h para MSVC. Además, soy consciente de que usar el ensamblaje en línea de C sería una mejor opción, ya que evita pensar en convenciones de llamada (consulte esta implementación ): solo tendría que pensar en las diferentes sintaxis del compilador. Sin embargo, me gustaría comenzar a practicar un poco con la integración de ensamblador y C.

Dado que ahora tengo que escribir una implementación de ensamblaje diferente para cada ensamblador principal (estaba pensando en GAS, MASM y NASM) y para cada uno de ellos tanto para x86-64 como para x86, ¿cómo debo manejar el hecho de que diferentes máquinas y C los compiladores pueden usar diferentes convenciones de llamada?

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

0

Si realmente desea escribir, como solo un ejercicio, una función de ensamblaje que "se ajuste" a todas las convenciones de llamada comunes para x86_64 (solo conozco la de Windows y la de System V), sin depender de atributos o indicadores del compilador para forzar la convención de llamadas, echemos un vistazo a lo que es común.

El orden de paso de Windows GPR es rcx , rdx , r8 , r9 . El orden de paso del System V es rdi , rsi , rdx , rcx , r8 , r9 . En ambos casos, rax tiene el valor de retorno si encaja y es una pieza de POD. Técnicamente hablando, puede salirse con la suya con una función llamada "políglota" si (0) guarda la unión de lo que cada ABI considera no volátil, y (1) devuelve algo que puede caber en un solo registro, y (2) toma no más de 2 argumentos GPR, porque la superposición ocurriría más allá de eso. Para ser absolutamente genérico, puede hacer que tome un solo puntero a alguna estructura que contenga cualquier dato de retorno arbitrario que desee.

Así que ahora nuestros argumentos vendrán a través de rcx y rdx o rdi y rsi . ¿Cómo saber cuál contendrá los argumentos? De hecho, no estoy seguro de una buena manera. Tal vez lo que podría hacer en su lugar es tener un contenedor que coloque los argumentos en el lugar correcto, y hacer que su función real tome argumentos de "relleno", de modo que sus argumentos siempre aterricen en rcx y rdx . Técnicamente, podría expandirse a r8 y r9 esta manera.

 #ifdef _WIN32 #define CPUID(information) cpuid(information, NULL, NULL, NULL) #else #define CPUID(information) cpuid(NULL, NULL, NULL, information) #endif // d duplicates a // c duplicates b no_more_than_64_bits_t cpuid(void * a, void * b, void * c, void * d);

Luego, en su ensamblaje, guarde la unión de lo que cada ABI considera no volátil, haga lo suyo, coloque la información que desee en la estructura a la que apunta rcx y restaure.

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