2011-01-09 11 views
5

¿Hay alguna manera de forzar a gcc a pasar los parámetros de una función en la pila?Forzar gcc para pasar los parámetros en la pila

No quiero utilizar los registros para el paso de parámetros.

actualización: I'am utilizando el brazo-gcc de CodeSourcery

+3

¿Por qué es malo pasar los parámetros en los registros? –

+0

No es algo malo. Solo quiero que los parámetros se pasen de esta manera porque estoy // emulando // una rutina de creación de hilos (y asignación de pilas). – cojocar

+0

¿Qué arquitectura/ABI? – ephemient

Respuesta

0

Según: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf

los primeros cuatro registros R0-R3 (a1-a4) se utilizan para pasar valores de argumento en una subrutina y para devolver un valor de resultado de una función. También pueden usarse para mantener los valores intermedios dentro de una rutina (pero, en general, solo entre llamadas de subrutina).

En ARM no existen otras convenciones de llamadas, pero sí las predeterminadas, que yo sepa. Y aquí está el por qué:

  1. ¿Por qué le gustaría? Su función no sería invocable en forma compilada por otras funciones, creando un desastre de compatibilidad.
  2. Sus llamadas a las funciones del sistema que cumplen con la ABI no funcionarían, a menos que el compilador fuera capaz de diferenciar entre convenciones de llamadas. Ahora, sé que en el pasado existen diferentes convenciones de llamadas para x86-32, pero observe cómo x64 es más simple (AMD64 que cualquier cosa que Microsoft haya hecho). ¿Por qué, al diseñar el ARM calling convention, permitirías tantas convenciones de llamadas diferentes? Crea un desastre de compatibilidad.
+1

Sí, tienes razón. Es algo * extraño * en esto, especialmente por las razones que has mencionado. La idea es que la función definida era el cuerpo principal de un hilo, en un entorno personalizado (SO). El sistema operativo personalizado empujaría el argumento del hilo en la pila. Para respetar el ABI, hay dos soluciones: poner el argumento en el r0 o declarar * thread_func (uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3, void * param) *. ¡Gracias! – cojocar

+1

¿Por qué no ponerlos en los registros de todos modos? Necesitarías preservar registros a través de hilos, pero de todos modos tienes que imaginarte si cambiaste los hilos durante la ejecución y los valores de registro de la función anterior se dejaron en su lugar ... si los sistemas operativos lo hicieran, sería muy complicado. –

+0

El subproceso se crea desde el espacio de usuario y no hay API (syscall) para establecer un valor de registro para el subproceso recién creado. – cojocar

1

Puede intentar envolver los parámetros en una estructura; por ejemplo, si su función es int calc_my_sum(int x, int y) {return x+y;} se puede cambiar de la siguiente manera (feo):

struct my_x_y { 
    int x, y; 
    my_x_y(): x(0), y(0) {} // a non-trivial constructor to make the type non-POD 
}; 

int calc_my_sum(my_x_y x_and_y) { 
    // passing non-POD object by value forces to use the stack 
    return x_and_y.x + x_and_y.y; 
} 

Como alternativa, puede simplemente añadir 4 parámetros ficticias para agotar los registros, por lo demás parámetros utilizará pila:

struct force_stack_usage { 
    int dummy0, dummy1, dummy2, dummy3; 
} 

int calc_my_sum(force_stack_usage, int x, int y) { 
    return x + y; 
} 
+0

¡Buen hack! La primera solución es solo C++, olvidé mencionar que necesitaba una solución en C. Gracias. – cojocar

+1

No es necesario que un constructor extraño de C++ logre lo que desea. En C las estructuras simplemente se copian en la pila. En C99 incluso podría llamar a la función con 'calc_my_sum ((my_x_y) {.x = 5, .y = 7})' o envolver tal cosa en una macro sin problemas. –

0

Dónde almacenar una variable local depende de cómo la usará. Si necesita obtener la dirección de una variable local, la variable local solo se puede almacenar en la pila. Entonces, cuando pasa su subrutina un puntero, este parámetro se pasará a través de la pila.

+0

No estoy seguro de si esto es abordar la pregunta o no ... – Nanomurf

Cuestiones relacionadas