Pregunta

Estoy empezando con el lenguaje ensamblador en Linux. He guardado el siguiente código como testasm.c
y compilado con: gcc testasm.c -otestasm
El compilador responde:. "Restricción imposible en‘asm’"

#include <stdio.h>
int main(void)
{
    int foo=10,bar=15;

    __asm__ __volatile__ ("addl %%ebx,%%eax"
        : "=eax"(foo) 
        : "eax"(foo), "ebx"(bar) 
        : "eax" 
    );

    printf("foo = %d", foo);

    return 0;
}

¿Cómo puedo resolver este problema? (He copiado el ejemplo de aquí .)

Debian Lenny, kernel 2.6.26-2-amd64
gcc versión 4.3.2 (Debian 4.3.2-1.1)

Resolución :
Ver la respuesta aceptada -. Parece que la cláusula de 'modificado' no se admite más

¿Fue útil?

Solución

__asm__ __volatile__ ("addl %%ebx,%%eax" : "=a"(foo) : "a"(foo), "b"(bar));

parece funcionar. Creo que la sintaxis de las limitaciones del registro cambiada en algún momento, pero no es terriblemente bien documentado. Me resulta más fácil escribir el montaje en bruto y evitar la molestia.

Otros consejos

Las limitaciones son solo letras (posiblemente con decoraciones adicionales), y se pueden especificar varias alternativas (es decir, un operando inmediato o regístrese es "ir"). Por lo que la limitación "eax" significa limitaciones "e" (signo de 32 bits constante entera), "a" (registro EAX), o "x" (cualquier registro SSE). Esto es un poco diferente que lo que quería decir ... OP y salida a una "e" claramente no tiene ningún sentido. Además, si algún operando (en este caso una entrada y una salida) debe ser igual a otra, se refieren a ella por una restricción número. No hay necesidad de decir eax se clobbered, es una salida. Se puede hacer referencia a los argumentos en el código en línea de 0%,% 1, ..., sin necesidad de utilizar nombres de los registros explícitos. Por lo que la versión correcta del código de la forma prevista por la OP sería:

#include <stdio.h>

int main(void)
{
    int foo=10, bar=15;

    __asm__ __volatile__ (
        "addl %2, %0"
        : "=a" (foo)
        : "0" (foo), "b" (bar)
    );

    printf("foo = %d", foo);

    return 0;
}

Una mejor solución sería permitir% 2 sea nada, y 0% de un registro (como x86 permite, sino que tendría que consultar el manual de la máquina):

#include <stdio.h>

int main(void)
{
    int foo=10, bar=15;

    __asm__ __volatile__ (
        "addl %2, %0"
        : "=r" (foo)
        : "0" (foo), "g" (bar)
    );

    printf("foo = %d", foo);

    return 0;
}

Si se quiere utilizar varias líneas, entonces esto también va a funcionar ..

  __asm__ __volatile__ (
        "addl %%ebx,%%eax; \
         addl %%eax, %%eax;" 
        : "=a"(foo) 
        : "a"(foo), "b"(bar)
    );

'\' debe añadirse para que el compilador para aceptar una cadena de varias líneas (las instrucciones).

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