Macro sustitución de un número constante de GAS
Pregunta
Lo que no se mal con esa macro en X86 GNU Asamblea?Se dice que el símbolo S es undefined durante el vínculo.
.macro S size=40
\size
.endm
Lo estoy usando como
mov %eax, S
Solución
Las macros se utilizan para crear plantillas para el código que usa con frecuencia, no para ingresar un número constante.Como tal, no creo que el ensamblador realice una expansión macro dentro de una expresión.Dado que simplemente desea un número, puede usar .set
para definir una constante.
.set S, 40
mov %eax, S
Además, en caso de que utilice habitualmente la sintaxis de Intel, asegúrese de darse cuenta de lo que hace este código: actualmente almacena el valor de eax en la memoria en la dirección 0x28.Si desea poner el número 40 en eax, debe invertir los operandos y usar un signo de dólar delante de S.
mov $S, %eax
Otros consejos
También puede asignar directamente los símbolos con el signo de igual =
:
S = 40
que la GNU como el manual dice que es equivalente a usar .set
https://sourceware.org/binutils/docs-2.19/as/Setting-Symbols.html#Setting-Symbols
Un símbolo se puede dar un valor arbitrario por escrito el símbolo, seguido por un signo igual
=', followed by an expression (see Expressions). This is equivalent to using the .set directive. See .set. In the same way, using a double equals sign
="=' aquí representa un equivalente de la .eqv directiva.Ver .eqv.
.equ
es otro sinónimo...
.equ S, 40
Un caso de uso típico de estas constantes, es calcular la longitud de la estática cadenas, por ejemplo,el Linux x86_64 hola mundo puede ser escrita como:
.data
hello_world:
.ascii "hello world\n"
hello_world_len = . - hello_world
.text
.global _start
_start:
/* write */
mov $1, %rax
mov $1, %rdi
mov $hello_world, %rsi
mov $hello_world_len, %rdx
syscall
/* exit */
mov $60, %rax
mov $0, %rdi
syscall
que se puede compilar y ejecutar wth:
as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out
%rdx
contendrá la longitud de la cadena ser por escrito.
El $
se requiere al igual que para cualquier regulares de la etiqueta de dirección, de lo contrario se estaría tratando de acceder a esa dirección de memoria en lugar de moverse de inmediato.