A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

Cap. II - Nossa primeira aplicação

Sex

14

Dez

2007


07:52

(4 votos, média 5.00 de 5) 


Nível intermediário

Masm32+RadASM

Capítulo II - Nossa primeira aplicação

Escrito por: ^A|An M0r3N0^
Conselheiro: RedH@wk
Tradução: ~Uglinho~
O presente texto foi escrito para fins educacionais e de pesquisa e é de livre distribuição contanto que se preserve o conteúdo e os direitos do autor.

A estrutura dos nossos programas

Para criar um programa em MASM32 deve-se seguir uma estrutura que o nosso compilador possa entender. Por exemplo:

.386 .model flat, stdcall option casemap:none include windows.inc include kernel32.inc includelib kernel32.lib .data .code Prog001: invoke ExitProcess,0 end Prog001

Com este código já criamos um programa que nosso compilador pode entender e assim criar nossa aplicação. Agora explicarei para que serve cada uma destas seções do código:

  • .386 - Esta diretiva serve para estabelecer o tipo de processador e as instruções com as quais irá trabalhar. Neste caso é um 80386.
  • .model flat, stdcall - Aqui estabelecemos o modelo de memória requerido para nossos programas de 32 bits.
  • option casemap:none - Esta opção torna possível a diferenciação de maiúsculas e minúsculas, por exemplo, "Z" é diferente de "z".
  • Include e Includelib - O MASM32 inclui arquivos e bibliotecas para manipular um grande número de funções que existem no Windows. Estas funções são conhecidas como API, como por exemplo a API ExitProcess que está em nosso código.

    O include se utiliza para adicionar arquivos com extensão .inc e .asm
    O includelib se utiliza para adicionar bibliotecas com extensão .lib

    O MASM32 também inclui o arquivo window.inc onde encontramos um grande número de constantes e estruturas usadas pelas funções do Windows (API).
  • .data - Existem dois tipos de informação, a informação inicializada e a não inicializada (.data?)
    1. Informação Inicializada (.data) - Nesta seção declaramos os dados que conhecemos, com os quais nosso programa se inicia. Por exemplo:
      .data
      EtiquetaTipo de variávelDados inicializados
      Msg_Textodb"BEM VINDO AO CURSO MASM + RADASM",0
      Valor_1dd7
    2. Informação Não Inicializada (.data?) - Nesta seção declaramos os dados que não conhecemos ou apenas estarão disponíveis quando o programa for executado. Normalmente a utilizamos para armazenar dados, por exemplo:
      .data?
      EtiquetaTipo de variávelDados inicializados
      Bufferdb128 dup (?)
      Valor_2dd?
  • .code - Depois das seções de dados, devemos indicar ao MASM32 onde começa o código do programa e também onde termina. Para isto colocamos uma etiqueta, por exemplo Prog001, seguida de ":", para indicar que abaixo começa o código do nosso programa e, ao terminar o código do programa, se escreve end mais a etiqueta que declaramos, ficando desta maneira: end Prog001

Programando no RadASM

Ao nosso código acima adicionaremos uma nova função para que mostre uma janela que nos dê boas vindas. Para isto abriremos o RadAsm.exe e começaremos a programar como mostra o video:

Vídeo 1
Prog001.exe

vovo Para assistir ao vídeo, faça o download de prog001.exe.


Explicando o vídeo Prog001.exe

No programa que desenvolvemos foram utilizadas duas funções: MessageBox e ExitProcess.

Se abrirmos nossa documentação das APIs do Windows (Win32 programmer's Reference) e buscarmos a função MessageBox, encontraremos o seguinte:

int MessageBox( 
     HWND hWnd, 
     LPCTSTR lpText, 
     LPCTSTR lpCaption,
     UINT uType 
);
  • hWnd - Este parâmetro serve para identificar o manipulador da janela mãe. No nosso caso colocamos NULL ou "0" porque ela não tem um manipulador (handle).
  • lpText - Aqui colocamos o endereço onde se encontra a nossa mensagem.
  • lpCaption - Este parâmetro funciona como a lpText, a diferença é que este é o título da janela com a mensagem.
  • uType - Este parâmetro é muito útil no momento de criar nossa janela - serve para personalizar a mensagem. Podemos especificar que tipo de botões desejamos usar e também o ícone. Por exemplo, no nosso programa foram usadas as seguintes constantes:
    BotõesÍcone
    Estas constantes estão declaradas no arquivo window.inc
    MB_OKMB_ICONINFORMATION

Para saber mais sobre esta função sugiro que você revise a documentação que mencionei anteriormente.

Em todo programa que escrevemos no MASM32 deve-se colocar a seguinte função:

VOID ExitProcess(  
     UINT uExitCode 
);

Com esta função encerramos o programa. No parâmetro uExitCode se especifica o código de saída, no nosso caso foi usado "0".

invoke - O MASM32 também tem uma sintaxe de alto nível que facilita a chamada de funções de forma correta e segura na hora de compilar - o MASM32 comprovará se os parâmetros das funções são adequados ou não. É usado desta maneira:

invoke FUNÇÃO, Argumentos

FUNÇÃO é onde escrevemos o nome da função que será usada.

Argumentos são os parâmetros das funções e devem ser separados por virgulas ",".

Operadores no arquivo prog001.asm

  • addr - Este operador serve para passar o endereço das nossas etiquetas para a função, por exemplo as etiquetas MsgTexto e MsgTitulo.
  • offset - É semelhante ao addr, mas com algumas diferenças como mostra o seguinte quadro:
addroffset
Não pode ser usado com instruções mnemônicas. Se utiliza com instruções mnemônicas.
Trabalha apenas com referências que estão adiante no código. Trabalha com referências que estão atrás ou adiante no código.
Pode operar com estruturas. Não pode operar com estruturas.

Operadores no arquivo prog001.inc

O Windows tem uma grande quantidade de APIs no seu sistema que são usadas por todos os programadores para Windows. Estas APIs ou Funções são encontradas nas bibliotecas de vínculo dinâmico (dynamic-linked libraries ou "DLL"), como por exemplo: user32.DLL, kernel32.DLL, shell32.DLL. Para podermos usar estas funções ou APIs em nossos programas, precisamos adicionar 2 arquivos para cada biblioteca:

  • user32.inc e kernel.inc - Nestes arquivos encontramos todas as funções declaradas que pertencem à user32.dll e à kernel32.dll respectivamente. Isto nos poupa tempo no momento de programar porque não precisamos declarar as funções que iremos usar. Vamos observar seu conteúdo para ver o que contêm. Para isto devemos abrir os arquivos .inc

Para abrir o arquivo, selecionamos o nome do arquivo .inc que desejamos abrir e pressionamos o botão direito do Mouse. Abre-se um menu onde clicamos na opção Abrir, como mostra a seguinte imagem:

Abrir .inc
Fig. 1

Depois se abre uma nova janelinha no RadAsm mostrando o seguinte:

user32
Fig. 2

Buscaremos nossa API MessageBox pressionando as teclas CTRL + F e escrevemos a função que vamos buscar, como mostra a seguinte imagem:

função
Fig. 3

Em seguida damos um clique no botão hallar/Buscar e encontramos o seguinte:

messagebox
Fig. 4

Já encontramos nossa função e comprovamos que esta API está declarada em user32.inc. Se buscarmos a outra API que utilizamos (ExitProcess), não a encontraremos porque esta API está em kernel.inc.

  • user32.lib e kernel.lib - Para que nosso programa possa se ligar com as bibliotecas de vínculo dinâmico do Windows, são necessárias informações como o nome da função e o endereço onde ela se encontra para que, no momento em que for executado, nosso programa carregue a biblioteca imediatamente. A informação mencionada se encontra nos arquivos .lib

Variáveis

TIPOS DE VARIÁVEIS
TipoAbreviaçãoEspaçoDescrição
BYTEDB1 byte ou 8 bits Cadeias de texto e caracteres
WORDDW2 bytes ou 16 bits Valor inteiro que vai de -32.786 a +65.535
DWORDDD4 bytes ou 32 bits Valor inteiro que vai de -2gb a +4gb
FWORD ou REAL4DF6 bytes ou 48 bits 48 bits com ponto flutuante
QWORD ou REAL8DQ8 bytes ou 64 bits 64 bits com ponto flutuante
TBYTE ou REAL10DF10 bytes ou 80 bits 80 bits com ponto flutuante

Vejamos alguns exemplos de como se deve declarar variáveis (nas seções .data e .data?):

Exemplo de dados inicializados

.data Texto db "BEM VINDO AO CURSO DE MASM + RADASM",0 Valor dd 77 Ponto df 4.575

Que vem a ser o mesmo que:

.data Texto BYTE "BEM VINDO AO CURSO DE MASM + RADASM",0 Valor DWORD 77 Ponto REAL4 4.575

Exemplo de dados não inicializados

.data Acumulador db ? Contador dd ? PFlutuante df ?

Que vem a ser o mesmo que:

.data Acumulador BYTE ? Contador DWORD ? PFlutuante REAL4 ?

Criando um modelo no RadASM

O programador do RadASM pensou em tudo e, para não voltarmos a escrever toda a estrutura dos nossos programas toda vez que quisermos programar, criamos um modelo como é mostrado no seguinte vídeo:

Vídeo 2
Creando Plantilla.exe

vovo Para assistir ao vídeo, faça o download de Creando Plantilla.exe.

Se quisermos ir para a pasta onde está nosso código fonte, abrimos o Menu Projeto/Abrir janela do projeto como mostra a imagem:

Janela do Projeto
Fig. 5

O que abre a pasta onde está nosso código fonte:

Pasta
Fig. 6

Exercício com dados não inicializados

No exercício anterior foram utilizados dados inicializados, agora falta criar um exemplo utilizando dados não inicializados:

prog001a.exe
prog001a.exe

vovo Para assistir ao vídeo, faça o download de prog001a.exe.

No exemplo Prog001a foi usada a função GetModuleFileName que é declarada da seguinte maneira:

Biblioteca kernel32.lib

GetModuleFileName,NULL,addr Buffer,225

Esta função extrai o diretório mais o nome da aplicação e o devolve na variável Buffer. Se Buffer já estiver ocupado, ele será modificado com os novos caracteres. O valor 225 significa o comprimento máximo de caracteres que serão devolvidos.

Buffer cumpre a função de armazenador de dados e é onde será armazenada a cadeia de texto devolvida pela função que foi utilizada.

Um programa mais complexo

Façamos nosso programa maior e um pouco mais complexo como mostrado no exemplo a seguir. Para isso utilizaremos a biblioteca masm32.lib.

O Masm32 possui sua própria biblioteca onde podemos encontrar muitas funções úteis, as quais muitas vezes precisamos e não levamos em conta. No seguinte vídeo utilizaremos algumas destas funções. Para isto vamos criar um programa que mostra o diretório da aplicação em uma mensagem e uma segunda mensagem que mostra o nome da aplicação que se está sendo executada:

prog002.exe
prog002.exe

vovo Para assistir ao vídeo, faça o download de prog002.exe.

Funções utilizadas no vídeo prog002.exe

Biblioteca masm32.lib

GetAppPath,addr Buffer

Esta função devolve o diretório da aplicação e o coloca na variável que definimos, neste caso Buffer, que ficará armazenado até que outra função substitua os dados que esta variável contém.

Biblioteca masm32.lib

NameFromPath,addr Buffer,addr NomeAplic

Como sabemos, Buffer contém o nome mais o diretório da aplicação porque já foi utilizado pela API GetModuleFileName. A função NameFromPath só extrairá o nome e o armazenará na variável NomeAplic.

  • Operador dup - significa duplicação. Se utiliza para alocar espaços na memória e sua sintaxe é a seguinte:
Contador dup (valor inicial)

Em contador escrevemos o tamanho que vamos duplicar. O valor inicial é escrito dentro dos parênteses, onde o sinal ? significa que o valor é indefinido.

No nosso código foi declarado da seguinte maneira:

EtiquetaVariávelContador DUPValor Inicial
Bufferdb225 dup(?)
NombreAppdb50 dup(?)

E significa o seguinte: Na variável Buffer foram separados 225 bytes na memória e na variável NombreApp foram separados 50 bytes na memória.

Recomendo que, se for utilizada uma variável para armazenar todo tipo de cadeias de texto devolvidas pelas funções, as variáveis declaradas tenham um espaço correspondente ao que se irá obter.

Você deve estar se perguntando porque se faz isto. É que quando você utiliza diversas variáveis no seu código, se não for alocado um espaço apropriado na memória para a dita variável, a cadeia de texto devolvida muitas vezes invade as outras variáveis e isto pode ocasionar problemas.


Exercícios

Com a ajuda do Win32 programmer's Reference, para saber o uso e os parâmetros referentes às funções faça estes exercícios:

  1. Criar novas mensagens utilizando a API MessageBox - exemplo prog001a:
    Mensagem
    Fig. 7
  2. No programa anterior adicionar a API MessageBeep, no lugar onde vocês desejarem.
  3. Crie um programa que mostre o diretório do Windows em uma mensagem e que depois mostre o diretório do Sistema em uma outra mensagem. Utilize as funções: GetWindowsDirectory e GetSystemDirectory.

Vocabulário

API (Application Programming Interface) - Interface de Programação de Aplicações. São funções de uso geral que se encontram no nosso Sistema Windows e que estão armazenadas em bibliotecas como, por exemplo, user32.dll e kernel32.dll.

Sintaxis - Sintaxe é uma forma de combinação das palavras segundo as regras estabelecidas pela linguagem de programação.

Mnemonic (Mnemônico) - Para facilitar o trabalho de escrever código de baixo nível, há muitos anos foi desenvolvido um sistema onde grupos de códigos operacionais semelhantes receberam nomes que lembram suas funções e que os tornaram muito mais práticos de serem usados. Estes nomes são denominados mnemônicos. Este é o sistema utilizado nos assemblers de 32 bits modernos.

Lembrando

Não esquecer de perguntar na lista MASM32-RadASM. As soluções destes exercícios serão enviados para a lista dentro de uma semana. Vocês também podem enviar suas prórias soluções.

Se tiverem dúvidas, sugestões ou outros, faça-as na lista de discussão.

O autor pode ser contactado

eMail: O endereço de e-mail address está sendo protegido de spambots. Você precisa ativar o JavaScript enabled para vê-lo. ou O endereço de e-mail address está sendo protegido de spambots. Você precisa ativar o JavaScript enabled para vê-lo.

Lista de discussão MASM32-RadASM

http://groups.google.es/group/MASM32-RadASM

www


Julio-2006
Copyright(c) 2005-2006 RVLCN



Recado da vó vovo

Aqui está o código fonte dos exercícios deste tutorial:

Vadim Logofet Sberbankарабский макияж для карихлобановский александр фотоasoft crmповышение эффективности бизнесаrestaurant nikasалександр лобановский

Informações adicionais