Uma
das grandes vantagens de estarmos programando em asm, de dentro
do Delphi, é que podemos aproveitar todas as estruturas
de programação dele e ainda brincar com as instruções
mais poderosas da face da Terra, digo, da programação
de computadores. Porém isso tem um custo: trabalho. Muito
trabalho.
Vamos então
criar uma rotina (procedure) que apenas e tão
somente crie um retângulo na tela, com uma determinada cor
(claro, vamos aproveitar o conhecimento da página anterior).
Para passar parâmetros
de um lugar para outro, poderíamos usar normalmente a estrutura
do pascal, mas aconselho a deixá-la de lado e lançar
mão de variáveis globais para esse propósito.
É mais seguro assim.
var Px,Py,Lrg,Alt,Cor: dword; |
Temos
então Px e Py que indicarão
as coordenadas iniciais ou posição na tela a ser
usada; Lrg e Alt como largura
e altura da figura a ser desenhada e Cor contendo
o valor 32 bits da cor usada para plotar. A forma de uso desta
estrutura é simples: carregamos cada uma das variáveis
com um determinado valor e chamamos a subrotina (procedure). Por
exemplo:
procedure TForm1.FormClick(Sender: TObject); begin Px:= 10; Py:= 10; Lrg:= 100; Alt:= 20; Cor:= $00FF0000; Box; Canvas.Draw(0,0,Tela); end;
|
Box portanto é nossa rotina de desenhar
retângulos na tela.
procedure TForm1.Box; asm push ebx //preserva ebx
//Calcular o endereço da coordenada Px,Py mov ebx,Init //início da tela 0,0 mov eax,Difr mov ecx,Py mul ecx //Py * Difr sub ebx,eax //calcula linha Py mov eax,4 mov ecx,Px mul ecx //Px * 4 add ebx,eax //endereço da coord Px,Py
//Plotar linha horizontal a partir de Px,Py mov ecx,Lrg mov eax,Cor @Lp1: mov [ebx],eax add ebx,4 loop @Lp1
//Plotar linha vertical a partir de Px+Lar,Py sub ebx,4 //recua um ponto mov ecx,Alt @Lp2: mov [ebx],eax sub ebx,Difr loop @Lp2
//Plotar linha horizontal a partir de Px+Lar,Py+Alt add ebx,Difr //recua um ponto mov ecx,Lrg @Lp3: mov [ebx],eax sub ebx,4 loop @Lp3
//Plotar linha vertical a partir de Px,Py+Alt add ebx,4 //recua um ponto mov ecx,Alt @Lp4: mov [ebx],eax add ebx,Difr loop @Lp4
pop ebx end;
|
Estude
com atenção a listagem e veja como o retângulo
é desenhado em seqüência, linha a linha, como
se o "lápis" não saísse do papel
em nenhum momento. Trabalhoso, não é mesmo? Em pascal
do Delphi isso seria mais ou menos o mesmo que fazer o seguinte:
Canvas.Rectangle(10,10,110,30);
|
Prosseguindo...
Uma
das observações que podemos fazer aqui é
que usaremos inúmeras vezes o cálculo da posição
inicial na tela, para a plotagem ou impressão de qualquer
figura, desenho, letra, ponto, etc. Então, nada mais natural
que transformemos esse cálculo em uma rotina separada e
obviamente precisaremos de mais uma variável global para
conter o resultado (o endereço em questão).
var Ender: dword;
procedure TForm1.PosXY; asm push ebx //preserva ebx
//Calcular o endereço da coordenada Px,Py mov ebx,Init //início da tela 0,0 mov eax,Difr mov ecx,Py mul ecx //Py * Difr sub ebx,eax //calcula linha Py mov eax,4 mov ecx,Px mul ecx //Px * 4 add ebx,eax //endereço da coord Px,Py mov Ender,ebx pop ebx end;
|
A
rotina para desenhar o retângulo fica então com a
seguinte modificação:
procedure TForm1.Box; asm push ebx //preserva ebx
call PosXY mov ebx,Ender
//Plotar linha horizontal a partir de Px,Py ...
|
O
interessante desse procedimento é que mantemos à
mão o endereço inicial para plotagem da figura e
isso pode ser útil de diversas formas. Pense em algumas
delas, enquanto a página seguinte é baixada para
o seu navegador.
|
Download...
Clique no link para fazer
o download dos arquivos fonte tratados nessa página.
asm2.zip...
(160 Kb) |
Fontes
do project 2. |
|
|