TRABALHANDO COM ESTRUTURAS
Silício ReversooicìliS ©
Assembly Intermediário
TEXTOS ACESSÓRIOS
Notice: Undefined variable: subtitulo in /home/numaboa.com.br/public_html/informatica/oiciliS/assembler/head.php on line 10

(ver 1.2 de 02.08.03)

Quando se escreve código para Windows, é comum manusear dados em bloco para alguns requisitos de codificação. O método normal é usar uma estrutura para agrupar dados de tal forma que possa ser endereçada como uma unidade.

Uma estrutura é constituída por membros que têm um tamanho de dados específico. Na estrutura RECT, muito utilizada, você tem quatro membros de tamanho DWORD.


	RECT STRUCT
		left DWORD ?
		top DWORD ?
		right DWORD ?
		bottom DWORD ?
	RECT ENDS

A notação para cada membro é nome do membro, tamanho do dado e especificador. Na maior parte das vezes o especificador é o ponto de interrogação (?), significando que o membro não foi inicializado com um valor.

A estrutura é escrita na memória como uma sequência de membros. No caso da estrutura RECT, ela é escrita na memória como quatro membros sequenciais de tamanho DWORD. Os membros de uma estrutura podem ser preenchidos de várias maneiras diferentes, dependendo da maneira como a estrutura foi originalmente alocada.

Se ela tiver sido alocada na seção .DATA, eles podem ser inicializados com valores predefinidos. Se tiver sido alocada na pilha, como uma variável local de um procedimento, os valores precisam ser inseridos nesta estrutura através de codificação.

	LOCAL Rct :RECT

		; código

		mov Rct.left, 1
		mov Rct.top, 2
		mov Rct.right, 3
		mov Rct.bottom, 4

É preciso salientar que um membro de estrutura é um operando de memória de modo que você não pode transferir diretamente outro operando de memória para ele. Você precisa usar um registrador para copiá-lo ou usar os mneumônicos de pilha push/pop.

Numa chamada com a diretiva invoke você pode se referir à estrutura preenchida como uma unidade com ADDR Rct. Se uma chamada de API necessitar do endereço de uma estrutura, você deve preencher a estrutura com os valores requeridos e depois chamar a API

	invoke chamadaAPI,parametro1,parametro2,ADDR Rct

Se você escrever um procedimento para o qual você queira passar os valores de uma estrutura, você pode passar esta estrutura usando os tipos de dados da estrutura no procedimento.

	MeuProc proc par1:DWORD,par2:DWORD,MeuRect:RECT
		mov eax, MeuRect.left ; copiar o primeiro membro para EAX

No procedimento que recebe RECT como parâmetro, cada um dos membros pode ser acessado através do seu nome. Você chama o procedimento da seguinte forma

	invoke MeuProc,par1, par2, Rct
Estruturas Aninhadas

Um método muito comum no Windows de 32 bits é o uso de estruturas aninhadas. O MASM possui uma notação que lida com este tipo de construção. Se você precisar de uma estrutura que possui múltiplas estruturas no seu interior

	MinhaEstruAninhada STRUCT

		item1 RECT <>
		item2 POINT <>

	MinhaEstruAninhada ENDS

Esta estrutura usa a estrutura RECT acima e a seguinte estrutura POINT

	POINT STRUCT
		x DWORD ?
		y DWORD ?
	POINT ENDS

Existem seis membros nesta estrutura, quatro da estrutura RECT e dois da estrutura POINT. Alocada na pilha, tem o seguinte aspecto

	LOCAL mea:MinhaEstruAninhada

Os seis membros desta estrutura são:

	mea.item1.left
	mea.item1.top
	mea.item1.right
	mea.item1.bottom
	mea.item2.x
	mea.item2.y

A notação para mea.item2.x significa a estrutura alocada mea, seu segundo item (item2) e o primeiro item da estrutura POINT (x).

Estruturas podem ser aninhadas em diversas profundidades, mas todas usam esta mesma notação e lógica básicas.

Uso avançado das estruturas

Cada vez mais existe a necessidade de manusear estruturas que são passadas como um endereço e este tipo de codificação está se tornando comum no design de código Windows. O MASM tem uma notação especializada para facilitar o uso deste processo.

Se, por exemplo, você precisasse passar o endereço de uma estrutura RECT para um procedimento, você normalmente iria fazer a chamada da seguinte maneira:

 
	invoke MinhaFuncao,ADDR Rct

No final do procedimento da chamada a esta função, você normalmente teria algo parecido com o seguinte:

 
	MinhaFuncao proc lpRect:DWORD

Com uma estrutura simples como a RECT, você pode endereçar manualmente cada um dos parâmetros colocando o endereço num registrador e escrevendo na localização de cada membro:

 
	mov eax, lpRct
	mov [eax], DWORD PTR 10
	mov [eax+4], DWORD PTR 12
	mov [eax+8], DWORD PTR 14
	mov [eax+12], DWORD PTR 16

Isto funciona muito bem porém, com estruturas mais complexas, fica mais difícil de trabalhar e a ocorrência de erros é mais provável.

A alternativa é usar um método que o MASM possui para endereçar cada um dos membros: a diretiva ASSUME.

	ASSUME eax:PTR RECT
		mov eax, lpRct

		mov [eax].left, 10
		mov [eax].top, 12
		mov [eax].right, 14
		mov [eax].bottom, 16

	ASSUME eax:nothing

Esta diretiva informa o assembler que o registrador EAX deve ser tratado como uma estrutura RECT. O ASSUME eax:nothing informa o assembler que o registrador não será mais usado desta maneira.

Há uma notação alternativa onde você pode fazer um "type cast" para cada membro:

 
	mov eax, lpRct

	mov (RECT PTR [eax]).left, 10
	mov (RECT PTR [eax]).top, 12
	mov (RECT PTR [eax]).right, 14
	mov (RECT PTR [eax]).bottom, 16

A vantagem destas técnicas é que elas usam a conveniência e a confiabilidade de uma estrutura, de modo que você não precisa calcular o offset de cada membro e ela também usa os nomes normais dos membros. A desvantagem destas técnicas é que elas usam um registrador, o que nem sempre é uma consequência desejada. Se o uso do registrador for um problema, você precisará alocar variáveis LOCAIS e copiar os dados de cada membro requerido para estas variáveis.




Localizador

| AAAA | Página Inicial | Mapa do Site | Novidades | Busca | Indique esta página | Mestre da Teia | Voltar |
| Localizador || @ Info NumaBoa > oicìliS > Assembly > Textos > Estruturas
Créditos: vovó Vicki

webdesign sobMedida by vickiSoft - /informatica/oiciliS/assembler/textos/estruturas.php (19.01.02) versão 1.2 de 02.08.03
Licença Creative Commons 1998-2006 Aldeia NumaBoa
Exceto onde especificamente declarado, todo material deste site é disponibilizado de acordo com a Licença Creative Commons.