2010-06-19 16 views
7

¿Cómo puedo usar definiciones externas como LONG_MIN y LONG_MAX en el código ensamblador ARM?Cómo usar C define en el ensamblador ARM

Digamos my_arm.h se parece a esto:

int my_arm(int foo); 

Digamos que tengo un my_main.c de la siguiente manera:

... 
#include <limits.h> 
#include "my_arm.h" 
... 
int main (int argc, char *argv[]) 
{ 
    int foo=0; 
... 
    printf("My arm assembler function returns (%d)\n", my_arm(foo)); 
... 
} 

Y my_arm.s se parece a esto:

.text 
    .align 2 
    .global my_arm 
    .type my_arm, %function 
my_arm: 
    ... 
    ADDS r1, r1, r2 
    BVS overflow 
    ... 
overflow: 
    LDR r0, LONG_MAX @ this is probably wrong, how to do it correctly? 
    BX lr @ return with max value 

La penúltima línea, no estoy seguro de cómo cargar correctamente, recuerdo vagamente haber leído en alguna parte, que tenía que definir LONG_MAX en .global, pero ya no puede encontrar el enlace a un ejemplo de trabajo.

Estoy compilando con la actualización del brazo-linux-gcc-gnueabi versión 4.3.2

==================

: Apreciar las sugerencias ! Lamentablemente, sigo teniendo problemas con la sintaxis.

En primer lugar, me hizo un poco mylimits.h archivo de cabecera (por ahora en el mismo directorio que .S)

#define MY_LONG_MIN 0x80000000 

en my_arm.S i añade lo siguiente:

... 
.include "mylimits.h" 
... 
ldr r7, =MY_LONG_MIN @ when it was working it was ldr r7, =0x80000000 
... 

dos problemas con este enfoque.

En primer lugar, el mayor problema: la MY_LONG_MIN símbolo no es reconocida ... así que algo no está bien es todavía

Segundo: sintaxis para .include no me deja incluir <limits.h>, tendría que añadir que en mylimits. h, parece un poco kludgy, pero supongo que está bien :)

¿Alguna sugerencia?

Tengo acceso a la Guía del Desarrollador del Sistema ARM Diseño y Optimización del Software del Sistema [2004] y Arquitectura ARM Manual de referencia [2000], mi objetivo es XScale-IXP42x Familia rev 2 (v5l) embargo.

+4

No sé sobre ARM, pero si en MIPS, cambiando el nombre a la extensión a .S hace C procesar previamente el archivo. – Tom

+0

use #include not .include, and .S not .s, como se dice en la respuesta. De esta manera explotarás una característica de gcc, y todo debe ir como para mis pruebas en x86, aparte de ensamblar que es diferente – ShinTakezou

Respuesta

11

A menudo, la extensión de archivo minúscula .s implica que el ensamblador no se debe pasar a través del preprocesador c, mientras que la extensión en mayúscula .S implica que debería. Depende de su compilador seguir esta convención (normalmente los puertos gcc lo hacen), por lo tanto, consulte su documentación.

(EDITAR: tenga en cuenta que puede utilizar las directivas #include, pero recuerde que la mayoría de los archivos que incluiría no serían normalmente ensambladores válidos (a menos que consistan enteramente en #define), por lo que es posible que tenga que escribir su propio encabezado que es)


edición 5 años más tarde:

Tenga en cuenta que el compilador armcc v5 sigue este comportamiento bajo Linux ... pero no en las ventanas.

+4

Si se usa la cadena de herramientas GCC, la macro '__ASSEMBLER__' se define al preprocesar los archivos de ensamblaje. Esto se puede usar para ayudar a que un archivo .h funcione en cualquier mundo (asm y C) si es necesario. Pero aún sería mejor segregar los elementos que deben funcionar en ambos mundos en encabezados separados, si es posible. Aunque para algo como 'LONG_MAX' que se define en un encabezado estándar, no tienes mucho control sobre ... –

+0

Sí, ¡no sirve de mucho con los encabezados estándar! (Excepto en ocasiones para los encabezados de arquitectura que definen cosas como las direcciones IO asignadas a la memoria, que están diseñadas para este propósito) – James

0

He visto simplemente alimentar gcc la fuente de ensamblador vs gas le permitirá hacer C cosas similares en ensamblador. En realidad, da un poco de miedo cuando te encuentras con situaciones en las que debes usar gcc como un front end de gas para hacer que algo funcione, pero esa es otra historia.

1

Lo que terminé haciendo es la siguiente:

en my_main.c

#include <limits.h> 
... 
int my_LONG_MAX=LONG_MAX; 

después en my_arm.S

ldr r8, =my_LONG_MAX 
ldr r10, [r8] 

Parece convuluted y es (además de las ganancias de portabilidad son cuestionables en este enfoque).

Debe haber una manera de acceder a LONG_MAX directamente en el ensamblaje. De tal manera que aceptaría gustosamente como la respuesta completa.

+0

si alguien quiere agregar una mejor solución, con mucho gusto aceptaré esa respuesta – Sint

+0

Esto es muy feo. ¿Por qué intentas usar definiciones relacionadas con el tamaño de tipo con el ensamblador de todos modos? Si tiene una única arquitectura (inherente a asm), simplemente escriba la constante literalmente. No va a cambiar! –

+0

Oh, es horrible, lo admito. :) Esta es una implementación de una función de biblioteca. Si me saliera con la mía, lo habría escrito como una constante directamente ... – Sint

2

Si está utilizando gcc y su ensamblador, es sencillo: nombre el archivo con .S final, luego agregue al principio #include <limits.h> y utilícelo donde lo necesite, p. Ej. ldr r0, SOMETHING; Hice pruebas con x86, ya que es lo que tengo, pero lo mismo funciona, ya que es una función de gcc.

0

uso --cpreproc para la opción armasm y añadir

#include "my_arm.h" 

en my_arm.s.

funciona para Keil ARM

Cuestiones relacionadas