¿Cómo almacenar y llamar una función compilada en C / C ++?

Para fines de optimización de muy bajo nivel, me sería útil si pudiera almacenar una función compilada dentro de una variable directamente,no Un puntero a una función. Es decir, si tengo una función foo, quiero hacer que un buffer de caracteres sea lo suficientemente grande como para contener las instrucciones de la máquina generadas para foo, y luego poder llamar a foo de alguna manera diciéndole a C que salte la ejecución al contenido de ese búfer (Supongamos que tengo un compilador intrínseco para asegurarme de que el búfer de caracteres esté alineado correctamente para mi arquitectura). Idealmente, me gustaría hacer esto manteniendo el uso del ensamblaje al mínimo (me doy cuenta de que es posible que se requieran algunos).

Mi mejor solución hasta ahora sería compilar un programa que tenga solo la función que deseo ensamblar con GCC, luego compilar en un código de máquina, luego usar las direcciones del ensamblado de salida para extraer el código de máquina deseado del ejecutable, luego rellenar manualmente el búfer con eso en mi programa, luego use el ensamblaje en línea para saltar a la dirección inicial del búfer. Eso es más truco y trabajo manual de lo que me gustaría.

No necesito compilar nuevas funciones en tiempo de ejecución, solo tengo que el búfer contiene instrucciones correspondientes a diferentes funciones ya compiladas durante el tiempo de ejecución. P.ej. Podría tener 3 funciones compiladas, y 1 búfer. Las 3 funciones son conocidas en tiempo de compilación, pero en tiempo de ejecución, el búfer puede corresponder a cualquiera de las 3 en diferentes momentos.

Edición: para aclarar lo que habría que ganar: tengo una estructura de la que este búfer será un miembro, y varios punteros a instancias de esa estructura. El búfer de cada estructura puede contener una función compilada diferente. Si tuviera que usar un puntero de función en lugar del búfer, tendría que cargar el puntero de función de la estructura, y luego quitar el puntero de función. Con el búfer, solo puedo saltar el contador del programa a un desplazamiento (la ubicación relativa del búfer) de la base de la estructura. Es un nivel menos de indirección. Para funciones muy pequeñas, esto puede ser un ahorro.

Edición 2: Más aclaraciones:

Con un puntero a función:

Cargue el puntero desde & struct + offsetof (puntero)Saltar a la ubicación contenida en el puntero.

Con un buffer que contiene código de máquina:

Saltar a & struct + offsetof (buffer)

El segundo es menos pasos.

Respuestas a la pregunta(12)

Su respuesta a la pregunta