¿Cómo se pasa una cadena como argumento para la instrucción “call” en ensamblador en línea?

StackOverflow https://stackoverflow.com/questions/2291002

  •  21-09-2019
  •  | 
  •  

Pregunta

En esencia, me gustaría ser capaz de hacer algo como esto:

//assume myFunction is defined and takes one argument that is an int
char * functionName = "myFunction";
int arg = 5;

__asm{
    push a
    call functionName
}

Básicamente quiero llamar a una función cuyo nombre está almacenado en una cadena. ¿Cuál sería la sintaxis adecuada para hacer esto?

Editar: Estamos hablando de ensamblador x86

¿Fue útil?

Solución

No se puede, al menos no directamente.

llamada toma una dirección como parámetro. A pesar de que se escribe "llamar functionName", el enlazador reemplaza functionname con la dirección real de la función. Que había necesidad de asignar primero esa cadena a su dirección. En general, C y C ++ no admiten ningún tipo de tiempo de ejecución de metadatos acerca de asignaciones de nombre de la función que permitan esto. Si la función se exporta desde un archivo DLL, puede utilizar GetProcAddress para encontrar su dirección.

Si la lista de funciones es estático, puede crear la correlación antes de tiempo a ti mismo.

Algo así como:

std:map<string, PVOID> functionMappings;
functionMappings["MyFunction"] = MyFunction;


// Later


PVOID function = functionMappings["MyFunction"];

__asm
{
    push a;
    call [function]
}

Algunas notas:

Creo que la norma dice que un puntero de función puede ser más grande que un PVOID. Esto debería funcionar en plataformas x86 / x64 de Windows.

No dijiste lo convención de llamada que estaba utilizando - este código supone stdcall

.

Esto es una cosa muy, muy extraño que quiere lograr - lo que es el problema que intenta resolver

Otros consejos

Esto no es posible, que está tratando de hacer una operación llamada por nombre. Ensamblador tiene solamente una llamada por valor donde el valor es una dirección. Es necesario para convertir el nombre a una dirección y pasar la dirección al ensamblador que significa que necesita algún tipo de referencia cruzada entre los nombres y direcciones. El compilador puede ayudarle a cabo aquí, en C y C ++ que necesita para buscar los punteros de función para ver la sintaxis necesaria para obtener la dirección de una función que luego se puede pasar al ensamblador.

Preferente: Sí, a veces, el compilador puede insertar símbolos en el ejecutable que podría ser buscado a través, pero eso es un método que está lleno de problemas. El formato de los datos pueden cambiar entre las versiones del compilador, la información puede ser despojado por el enlazador y así sucesivamente.

Respuesta corta: olvidarse de él, si eso es permisible, lo más probable es ser demasiado difícil de implementar

.

Respuesta larga: La forma más sencilla que puedo pensar para hacer esto sería la creación de una tabla de consulta que se asigna a las cadenas de funciones (o más exactamente, para funcionar punteros). Primero tendría que pensar en una estructura de datos razonable para la celebración de ese mapa, e implementar una función de comparación de cadenas con el fin de comparar functionName a las teclas durante una consulta. Por último, pero no menos importante, que tendría que cargar manualmente las entradas de correlación en esa estructura de la tabla.

(no voy a entrar en alguna información más específica, en primer lugar porque mis días son ensamblador en el pasado ahora, y en segundo lugar, porque soy un poco de curiosidad para averiguar si no se podía lograr lo que quiere que ver con la otra, más fácil de implementar la solución ... lo siento.)

No sé de ninguna manera de hacer esto fácilmente. En algunos lenguajes de alto nivel se puede utilizar la reflexión para lograr esto, pero ni C ni el montaje tiene esa funcionalidad disponible. En el momento en el enlazador se realiza todas las funciones llamadas se resuelven a direcciones. Tal vez si tuvo acceso a algunas infraestructuras de depuración que podría hacer una búsqueda inversa en el nombre de la función para obtener su dirección, pero que no sería una cosa trivial para lograr de montaje.

O usted podría utilizar punteros a funciones definidas en tiempo de compilación para almacenar las direcciones de las funciones que le interesan (aunque todavía había necesidad alguna manera de traducir su cadena a un puntero de función, presumiblemente a través de una cadena comparar búsqueda en la tabla) . Si esto es algo que está interesado en hacer que te sugiero escribir el equivalente C y luego mirar el código ensamblador que las salidas del compilador para ver cómo se maneja punteros de función.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top