2012-09-19 12 views
7

Estoy trabajando con el ensamblado ARM, donde tengo que escribir una subrutina para la cual sigo la convención de llamadas ARM (esto tendrá que integrarse con alguna implementación separada de nivel superior en algún lado else) para pasar parámetros y devolver valores. Ahora aquí hay algo que no estoy seguro en general cuando se trabaja con ensamblaje.Pasando parámetros y valores de retorno para una subrutina en el ensamblaje

De acuerdo con la convención, si entiendo bien, los argumentos se pasan en orden comenzando por los registros r0 - r4 y luego por otros argumentos se usan pilas. Los valores de retorno se pasan a r0.

Ahora aquí es con lo que estoy confundido. Si se supone que debo guardar el contexto de r0 y desactivarlo después de que no haya forma de devolver el resultado, la única forma en que se puede hacer es corromper el primer argumento. ¿Hay alguna solución de alguna manera? ¡Gracias de antemano chicos!

Respuesta

6

Cuando devuelve el valor de retorno en r0, la persona que llama espera que lo haga. La persona que llama no espera que r0 todavía contenga el mismo valor que el primer parámetro original, porque r0 es específicamente donde está el valor de retorno.

Normalmente el ARM calling convention requires that the subroutine preserves r4 through r11, no r0 a r3. Entonces no hay contradicción de todos modos.

+0

Supongo que es responsabilidad del que llama guardar el contexto de r0 antes de invocar la función. – as3rdaccount

+0

Desde el enlace que publicó: * "r0 a r3: utilizado para mantener los valores de argumento pasados ​​a una subrutina, y también mantener los resultados devueltos desde una subrutina" *. – m0skit0

6

¿Por qué no probarlo solo y ver qué hace el compilador?

unsigned int fun (unsigned int a, unsigned int b) 
{ 
    return(a+b); 
} 

compilación para objeto y desmontar

arm-none-eabi-gcc -O2 -c fun.c -o fun.o 
arm-none-eabi-objdump -D fun.o 

y el resultado es

00000000 <fun>: 
    0: e0810000 add r0, r1, r0 
    4: e12fff1e bx lr 

El dos entradas A y B se pasan en el uso de r0 y r1. r0-r4 no tiene que ser preservado, en particular r0 porque es el valor de retorno no puede ser preservado. Entonces, como el código C requiere, los dos operandos se suman, y como la convención de llamada requiere, el resultado se devuelve en r0. r0 = r0 + r1.

El compilador debe cumplir con la convención, de lo contrario, el código que produce no funcionará, por lo que puede simplemente compilar el código y desmontarlo para obtener más información sobre la convención de llamadas para un compilador y objetivo en particular.

Cuestiones relacionadas