Arrays (vetores) em Assembly - A diretiva TIMES

Neste tutorial de nosso Curso de Assembly, iremos continuar falando sobre a alocação de memória.
No caso, falaremos de alocação de blocos contínuos de memória, popularmente conhecidos como vetores (C, C++) ou arrays (Java).

Lembramos que vetores e arrays em Assembly são um vasto conteúdo, há uma série de possibilidades e conceitos por trás desta ideia, e ainda veremos muito sobre o assunto em nosso curso.
Porém, este tutorial está na seção básica e se destina a apresentar as ideias iniciais, alocação e inicialização de elementos de um vetor.

Array ou Vetor em Assembly

No tutorial passado de nosso curso falamos sobre as diretivas DEFINE e RES para alocar e reservar memória, e é de vital importância que você tenha estudado, entendido e com o assunto fresco em mente para que continuemos nosso curso, pois iremos continuar falando sobre alocar memória em Assembly.

Naquele artigo mostramos como declarar variáveis, dando um nome para elas e definindo o tanto de bytes que iremos separar em memória somente para aquelas variáveis, através de comandos como DB e DW.

Mas se notar bem, alocamos alguns espaços, manualmente.
E se for necessário alocar mil bytes diferentes, para armazenar números quando você for projetar o hardware de um microondas?
Um sistema como um relógio digital é complexo e pode usar dezenas de milhares de bytes facilmente, e como os recursos são poucos, é necessário usar a linguagem Assembly.

E é claro que você não vai manusear cada byte desses (embora programadores Assembly sejam conhecidos por serem escovadores de bits), e é para isso que existem os arrays, também conhecidos por vetores.

Um vetor, ou array, nada mais é que um bloco enorme de bytes, onde cada bloco é usado como uma variável, digamos assim, pois trabalhamos diretamente com bytes de memória, não importa se seja pra um inteiro, caractere ou booleano, pois essas ideias são de linguagens de alto nível, que abstraem diversos conceitos do que realmente ocorre por debaixo dos panos.

Para nós, vetor ou array em Assembly é um bloco de bytes, geralmente grande, para que possamos manipular uma quantidade maior de informações de uma maneira bem mais simples, óbvia e lógica.
No decorrer de nosso curso nos depararemos diversas vezes com arrays.





A diretiva TIMES: Como declarar e inicializar um vetor/array em Assembly

Para alocarmos memória usamos a diretiva define, mais conhecida pelas abreviações DW, DD, DQ etc, e principalmente pela DB (define byte).

Para alocar um bloco de vários bytes ainda utilizaremos a define, mas precisamos dizer quantas vezes esta alocação deve ocorrer.

Para dizermos o tanto de vezes (de blocos de bytes) que queremos alocar, vamos usar a diretiva TIMES (que pode ser traduzida como vezes . 3 times -> 3 vezes, 4 times-> 4 vezes).
Em seguida, devemos dizer o número de vezes que a define vai se repetir.

Após nomear, usar a TIMES, dizer o tanto de vezes que a alocação de bytes deve ser feita, devemos obviamente dizer quantos bytes vão ser alocados por vez.
E como sabemos, para alocar bytes usamos os comandos DB, DW, DD, DQ e DT.

E por fim, devemos dar um valor inicial para esses bytes do bloco de memória.
Você pode alocar 1 milhão de blocos de DT (cada DT aloca 10 bytes), e inicializar cada um deles com um valor numérico, de forma totalmente automática.

Assim, a sintaxe geral para se declarar um vetor/array em Assembly é:
nomeDoBloco       TIMES    numeroDeVezes    diretivaDEFINE    valorInicial

Vamos criar um array de nome "vetor", cada elemento do vetor vai ser alocado através de um DB, esse vetor terá 10 elementos (então vamos repetir 10 vezes a alocação DB) e vamos inicializar todos os elementos de nosso array com valor 0:
vetor      TIMES    10    DB    0

Agora vamos declarar um vetor de nome "array", ele será composto de 20 elementos do tipo word (2 bytes cada), e será inicializado com o valor hexadecimal FFH:
array       TIMES    20    DW    FFH

Espaços contíguos de memória Assembly

Um fato interessante que ocorre na linguagem de programação Assembly é que, ao reservar e alocar espaços de memória, isso é geralmente feito de modo que os blocos de memória sejam contíguos, ou seja, vizinhos.

Por exemplo, vamos supor que nossa variável "elemento1' ocupe um byte, vamos dizer que na posição "x" de memória:
elemento1      DB   00H

Se formos, em seguida, alocar a variável "elemento2" que é do tipo e word e ocupa 2 bytes, ela vai estar na posição "x+1" de memória, pois na posição "x" está o "elemento1" e ele ocupa 1 byte:

A próxima variável que declararmos vai estar na posição "x+3", pois o local "x" é ocupado por "elemento1" e os dois bytes seguintes é ocupado por "elemento2", concorda?

Vamos fazer a seguinte declaração:
elemento1      DB   00H
elemento2      DW   01H
vetor1         TIMES   10   DB   0
vetor2         TIMES   20   DW   0
elemento3      DD   0

Note que que o "vetor1" ocupa 10x1=10 bytes, pois ele aloca 10 elementos do tipo byte (DB).
E como dissemos, o "vetor1" vai inicial no local de memória "x+3", como ele ocupa 10 bytes, o próximo vetor vai se iniciar na posição "x+3+10", ou seja, "vetor2" começa na posição "x+13", ok?

Agora vamos analisar "vetor2", ele declara um bloco de memória de 20 elementos do tipo WORD, onde cada um destes ocupada 2 bytes. Então "vetor2" ocupada 20x2=40 bytes.

Entendeu mesmo?
Então em que posição de memória vai estar localizada a variável "elemento3"?
A resposta está em branco ao lado (seleciona o local com o mouse): x+13+40 = x+53

E caso deseje declarar outra variável abaixo de "elemento3", em que posição de memória esta variável vai começar? (lembre-se que "elemento3" ocupa 4 bytes): x+53+4 = x+57

3 comentários:

Anônimo disse...

Como posso fazer para criar um vetor
exemplo:
vet [100]

e depois eu colocar algo nas posicoes dele
tipo vet[i] = 5 e por ai vai

equipe conhecimento disse...

muito bom. ansioso pelas próximas postagem, ensinas muito bem.

Noel disse...

Se em C eu fizesse...
struct {
char elemento1;
short elemento2;
char vetor1[10];
short vetor2[20];
int elemento3;
} estrutura;

estrutura.elemento1 = '\0';
estrutura.elemento2 = 1;
estrutura.vetor1[0] = '\0';
estrutura.vetor2[0] = 0;
estrutura.elemento3 = 0;

o equivalente em asm seria? É assim que eu poderia criar uma struct em asm?
.bss
elemento1 resb 1
elemento2 resw 1
vetor1 resb 10
vetor2 resw 20
elemento3 resd 1

.data
estrutura:
elemento1 db 0
elemento2 dw 1
vetor1 times 10 db 0
vetor2 times 20 dw 0
elemento3 dd 0