Escovando menos bits com Nasm
Nasm é um montador para processadores 80x86 com sintaxe Intel™
e tem algumas macros que substituem textos
e podem melhorar muito a nossa produtividade.
Nasm é um montador para processadores 80x86 com sintaxe Intel™
e tem algumas macros que substituem textos
e podem melhorar muito a nossa produtividade.
Este exemplo presume que você já tenha alguma interesse na linguagem assembly, e já compilou um programa feito com o NASM no Linux seguindo, por exemplo, as dicas do Linux Assembly How-To , que oferece uma introdução bastante simples de como fazer uma chamada de sistema e compilar o código fonte.
Um trecho de código em assembly às vezes dá muito trabalho. Alguns deles podem ser usados diversas vezes, e é aí que entram as macros. Esse exemplo pode não ser o melhor, mas ainda assim pode ser um bom começo:
Vamos escrever um macro para exibir strings, como varíaveis ou como constantes. Depois de escrita ela pode ser usada diversas vezes em um arquivo separado, e pode ser o começo da sua biblioteca de macros. Não entraremos em todos os detalhes da implementação aqui. O código fonte está disponível logo abaixo para leitura, e você pode examinar com mais cuidado, modificar e até melhorar se quiser.
%macro @STRING 2
%1:db %2
strlen%1 equ $ - %1
%endmacro
A macro acima cria espaço na memória para um string cujo nome ou identificador entra como primeiro argumento (%1) e valor como segundo argumento (%2). Ela serve para declarar um string qualquer, de tamanho arbitrário; esse tamanho, porém. fica sempre salvo em uma constante dada por
strlen%1 equ $ - %1
cujo nome real vai ser resolvido pela junção da palavra strlen e o nome do identificador da variável (por exemplo, strlenmeustring) .
Precisamos também de uma macro auxiliar que teste para saber se se trata de um string constante ou de uma variável.
Além disso ela pode criar seções extras de código e de dados automaticamente para declarar os strings constantes que chegam como argumento;
quando se trata de uma varíavel, ela simplesmente chama @sys_write para executar a sua tarefa. é o que vem a seguir:
%macro @puts 1
%ifstr %1
section .data
%%str: db %1
strlen%%str equ $ - %%str
section .text
@sys_write %%str
%else
@sys_write %1
%endif
%endmacro
A implementação de sys_write é relativamente trivial:
%macro @sys_write 1
mov edx, strlen%1
mov ecx,%1
mov ebx,1
mov eax,4
int 0x80
%endmacro
Finalmente, a nossa macro principal, que pode receber diversos argumentos de strings, constantes ou variáveis, e exibi-los na tela:
%macro @WRITE 1-*
%rep %0
@puts %1
%rotate 1
%endrep
%endmacro
Exemplo de uso dessa macro:
@puts {"Eu posso imprimir qualquer string com esta macro!!!",@CR}
@WRITE "Mas essa macro aqui é bem melhor!!",msg1, msg2, "Você não concorda?!!"
Importante: se você usar dados que não são strings (por exemplo, o código do retorno do carro), deve usar esta sintaxe na declaração:
@STRING mensagem, {" Hello, World!", 0x0A }
- Mais detalhes sobre as macros do NASM em http://www.nasm.us/doc/nasmdoc4.html
$ nasm -f elf hellow-2.asm
$ ld -s -o hellow-2 hellow-2.o
$ ./hellow-2
Aqui vão alguns links onde você pode encontrar exemplos de programação com NASM.