Macro substituindo um número constante no GAS
Pergunta
O que há de errado com essa macro no X86 GNU Assembly?Diz que o símbolo S é indefinido durante a vinculação.
.macro S size=40
\size
.endm
Estou usando como
mov %eax, S
Solução
As macros são usadas para criar modelos de código que você usa com frequência, não para inserir um número constante.Como tal, não acredito que o montador faça expansão macro dentro de uma expressão.Como você simplesmente deseja um número, pode usar .set
para definir uma constante.
.set S, 40
mov %eax, S
Além disso, caso você use a sintaxe intel, certifique-se de perceber o que esse código está fazendo: ele atualmente armazena o valor de eax na memória no endereço 0x28.Se você quiser colocar o número 40 em eax, precisará inverter os operandos e usar um cifrão na frente de S.
mov $S, %eax
Outras dicas
Você também pode atribuir símbolos diretamente com o sinal de igual =
:
S = 40
que o GNU como manual diz é equivalente a usar .set
https://sourceware.org/binutils/docs-2.19/as/Setting-Symbols.html#Setting-Symbols
Um símbolo pode receber um valor arbitrário escrevendo um símbolo, seguido por um sinal de 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
= '`=' aqui representa um equivalente da diretiva .eqv. Veja .eqv.
.equ
é outro sinônimo ...
.equ S, 40
Um caso de uso típico de tais constantes é calcular o comprimento de strings estáticas, por exemplo, o Linux x86_64 hello world pode ser escrito 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 você pode compilar e executar com:
as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out
%rdx
conterá então o comprimento da string a ser escrita.
O $
é necessário como para qualquer etiqueta de endereço regular, caso contrário, você tentaria acessar esse endereço de memória em vez de mover um imediato.