Informática Numaboa - Tutoriais e Programação
Message Box (masm)
Sab 16 Dez 2006 11:41 |
- Detalhes
- Categoria: Assembly Numaboa (antigo oiciliS)
- Atualização: Terça, 16 Fevereiro 2010 22:40
- Autor: vovó Vicki
- Acessos: 21642
offset e addr
As variáveis TituloJanela e TextoJanela são as duas que precisavam ser inicializadas antes de se chamar a função MessageBox. De acordo com a referência da API, a função pede o PONTEIRO para estas variáveis e não o valor das mesmas. Para enviar um ponteiro de endereço como parâmetro usa-se tradicionalmente o operador offset. Se optarmos por chamar a função através de INVOKE, podemos utilizar o operador addr. Os dois modos são válidos, mas você precisa conhecer a diferença entre eles:
- addr não aceita referências posteriores, enquanto offset aceita. Por exemplo, se o rótulo/variável for definido no código fonte adiante da linha que o invoca, addr não irá funcionar.
invoke MessageBox, NULL, addr TextoJanela, addr TituloJanela, MB_OK
O MASM vai informar um erro. Se você usar offset ao invés de addr no trecho de código acima, o MASM vai assemblar numa boa.
...
TituloJanela db "Tutorial NumaBoa 3",0
TextoJanela db "Message Box NumaBoa",0 - addr pode lidar com variáveis locais, o offset só com variáveis globais. Uma variável local é apenas algum espaço reservado na pilha. Você vai conhecer seu endereço apenas em tempo de execução. offset é interpretado pelo assembler em tempo de construção (assemblamento, assemblagem, assemblação, sei lá :blush: ) e aí fica claro porque offset não pode funcionar para variáveis locais. addr é capaz de lidar com variáveis locais devido ao fato do assembler primeiro checar se a variável referenciada por addr é global ou local. Se for uma variável global, ele põe o endereço dessa variável no arquivo objeto. Sob este aspecto, addr funciona como o offset. Se for uma variável local, ele gera uma sequência de instruções, antes da chamada à função, parecida com o seguinte:
lea eax, LocalVar
Uma vez que lea pode determinar o endereço do rótulo em tempo de execução, a coisa funciona bem.
push eax
Então vamos lá. Após todo este trabalho de preparação, adicione a chamada à função na área de código:
.386
.MODEL FLAT,STDCALL
option casemap:none
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\windows.inc
.DATA
TituloJanela db "Tutorial NumaBoa 3",0
TextoJanela db "Message Box NumaBoa",0
.CODE
inicio:
invoke MessageBox, NULL, addr TextoJanela, addr TituloJanela, MB_OK
invoke ExitProcess,0
end inicio
Pelo exposto acima, você deve ter sacado que existem outras chamadas válidas. A tradicional seria fazer um push para a pilha dos parâmetros em ordem inversa (convenção C de passagem de parâmetros) e depois chamar a função com um call:
push MB_OK
push offset TituloJanela
push offset TextoJanela
push NULL
call MessageBox
Criando a Janela
Se você optou pelo texto com a chamada de alto nível, o arquivo texto completo deve estar como o mostrado logo a seguir. Note que foi adicionado um ícone à janela, o MB_EXCLAMATION. Podemos enviar o parâmetro do tipo de janela como MB_OK OR MB_ICONEXCLAMATION ou como MB_OK+MB_ICONEXCLAMATION. O assembler aceita as duas versões.
.386
.MODEL FLAT,STDCALL
option casemap:none
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\windows.inc
.DATA
TituloJanela db "Tutorial NumaBoa 3",0
TextoJanela db "Message Box NumaBoa",0
.CODE
inicio:
invoke MessageBox, NULL, addr TextoJanela, addr TituloJanela, MB_OK+MB_ICONEXCLAMATION
invoke ExitProcess,0
end inicio
Agora é só produzir o executável. No tutorial anterior, "O Folgado", vimos como assemblar e linkar o arquivo texto usando as opções correspondentes do menu do MASM. Desta vez, vamos fazer o trabalho na unha:
- Salve o exemplo com um nome qualquer, por exemplo, msgbox.asm
- Transforme o arquivo texto em arquivo objeto usando o construtor do MASM chamado ML.EXE. Este programa fica no diretório \masm32\bin. Se este diretório estiver no path, use a seguinte linha de comando: ml /c /coff /Cp msgbox.asm
- /c indica ao MASM para apenas assemblar, ou seja, ele não vai chamar o link.exe automaticamente. É conveniente rodar apenas o construtor para verificar se há algum erro no arquivo texto. Se tudo estiver correto, chamamos o link.exe posteriormente.
- /coff indica ao MASM para criar o arquivo .obj no formato COFF. O MASM usa uma variação do COFF (Common Object File Format) que é usado em sistemas UNIX como formato próprio de arquivos objeto e executáveis.
- /Cp indica ao MASM para preservar maiúsculas e minúsculas dos identificadores usados. Se você incluir \masm32\include\windows.inc, então pode colocar "option casemap:none" no cabeçalho do código fonte, logo abaixo da diretiva .model, para obter o mesmo resultado.
- Se não houve mensagens de erro, você pode transformar o arquivo objeto msgbox.obj em executável. Use o linker do MASM, o LINKER.EXE, que também se encontra no diretório \masm32\bin, com a seguinte linha de comando: link /SUBSYSTEM:WINDOWS/LIBPATH:c\masm32\lib msgbox.obj
- /SUBSYSTEM:WINDOWS informa ao linker o tipo de executável que deve ser criado.
- /LIBPATH: informa a localização das bibliotecas de importação. No MASM32, elas estarão no diretório masm32\lib.
Se tudo correu bem, agora você é o feliz possuidor de um executável denominado msgbox.exe, de apenas 2.560 bytes, cuja função é mostrar esta janelinha: