Suma la dirección de var mem a eax valor de registro en lugar de valor var.
Sí, la sintaxis del ensamblaje en línea de gcc es bastante arcana. Parafraseando desde la sección correspondiente en el GCC Inline Assembly HOWTO"m"
aproximadamente le da la ubicación de la memoria de la variable C.
Es lo que usarías cuando solo quieres una dirección desde la que puedas escribir o leer. Observe que dije la ubicación de la variable C, por lo que %0
se establece en la dirección de Word32 *var
- tiene un puntero a un puntero. Una traducción C del bloque de ensamblaje en línea podría parecerse a EAX += *(&var)
porque puede decir que la restricción "m"
toma implícitamente la dirección de la variable C y le da una expresión de dirección, que luego agrega al %eax
.
¿Hay alguna forma de decirle a la instrucción addl que use var value en lugar de var mem address sin copiar var mem address en un registro?
Eso depende de lo que signifique. Que necesita para obtener var
de la pila, por lo que alguien tiene que eliminar la referencia de la memoria (ver @Bo Perssons respuesta), pero no tiene que hacerlo en ensamblador en línea
La restricción es necesario que haya "m"(*var)
(como se sugirió @fazo) Esto le dará la ubicación de memoria del valor var
apuntando a, en lugar de una ubicación de memoria que apunta a él.
El código generado es ahora:
test_func:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
#APP
# 2 "test.c" 1
addl (%eax), %eax
# 0 "" 2
#NO_APP
popl %ebp
ret
que es un poco sospechoso, pero eso es comprensible, ya que se olvidó de decirle a gcc que Demolí (modificada sin tener en la lista de entrada/salida) %eax
. La fijación que genera asm("addl %0, %%eax" : : "m"(*var) : "%eax")
:
movl 8(%ebp), %edx
addl (%edx), %eax
Lo cual no es mejor o más correcto en este caso, pero siempre es una buena práctica para recordar. Consulte la sección en el clobber list y preste especial atención al "memory"
clobber para el uso avanzado del ensamblaje en línea.
Aunque no desee (explícitamente) cargar la dirección de memoria en un registro, la cubriré brevemente. Cambio de la restricción "m"
-"r"
casi parece funcionar, las secciones pertinentes se cambia a (si incluimos %eax
en la lista clobber):
movl 8(%ebp), %edx
addl %edx, %eax
que es casi correcta, hemos cargado el valor del puntero var
en un registro, pero ahora tenemos que especificarnos que estamos cargando desde la memoria. Cambiar el código para que coincida con la restricción (por lo general indeseable, sólo estoy mostrando que esté completa):
asm("addl (%0), %%eax" : : "r"(var) : "%eax");
Da:
movl 8(%ebp), %edx
addl (%edx), %eax
El mismo que con "m"
.
Su asm en línea no define lo que se supone que está en EAX, así que gcc podría poner nada allí ... ¿qué estás realmente tratando de hacer? – servn