Define - Como alocar memória Assembly - RES, como reservar memória

Se você estudou somente linguagens de altíssimo nível, como as de linguagens de script, com certeza nunca se preocupou em alocar memória, pois é tudo feito automaticamente por debaixo dos panos.

Se estudou linguagens como C ou Java, você alocava espaço na memória ao declarar variáveis e estruturas (em C é possível ainda, a alocação dinâmica de memória).

Nesse tutorial de nosso curso de Assembly, vamos aprender como reservar espaço em disco em Assembly, ver quais as diferenças e peculiaridades nessa linguagem de baixo nível.


Alocação de memória em programação

Em outras linguagens de programação, para declarar variáveis precisávamos definir o tipo antes.

Por exemplo, em C ou C++, escrevíamos 'int' para inteiros, 'float' ou 'double' para decimais, 'char' para caracteres, dentre outros tipos.

Ao fazermos isso, sem saber (diferente do Assembly, em que vemos claramente como as coisas são feitas), estamos dizendo muito mais do que simplesmente a alocação de memória em si.

O resultado de uma operação entre um inteiro e um decimal não é totalmente previsível, depende da variável em que vamos armazenar, da linguagem e de outras regra específicas.

Quando declaramos uma variável do tipo double ou float, já fica subentendido que haverá uma vírgula (ou ponto), representado sua parte decimal. Além disso, há divisões no espaço alocado de memória, para armazenar a parte decimal e a parte não decimal.

Enfim, acontece muito mais do que simplesmente reservar um espaço de memória. Muitas rotinas úteis, que facilitam a vida de programador acontecem por debaixo dos panos.





























Alocação de memória em Assembly - A diretiva define

Obviamente, em Assembly as coisas são um pouco diferente.

Essas coisas que atuam sem o conhecimento do programador simplesmente não existem, e o profissional que programa em Assembly ficará a cargo de tudo.

Em Assembly, você realmente irá alocar espaço em memória. E somente isso.

Por exemplo, usamos o mnemônico ADD para adicionar um número a outro. Mas ele não vai simplesmente adicionar todos e quais números automaticamente como costumamos fazer em outras linguagens.

Se o resultado der mais de dois dígitos, por exemplo, você terá que fazer uma rotina para exibir esses dois dígitos (sabe quando você soma no papel, fazendo continha e o valor da soma dá mais que 9, aí 'vai 1' ou 'sobe 1' ? é algo parecido) ; ao somar, ter cuidado para saber se somou o caractere '1' ou realmente o número 1. Case seja caractere, ou queira exibir, terá que fazer alterações, e por aí vai.

Como enfatizamos, Assembly é em baixo nível.

Trabalhamos com bits e bytes. E nesse nível, as coisas não vem prontas.

O programador Assembly é que o tem o poder e responsabilidade de absolutamente tudo. Por isso, ao alocar memória, temos que definir o número de bytes que vamos usar.

Vamos usar as seguintes variações da diretiva define: DB, DW, DD, DQ e DT.

Eles significam e alocam determinados número de bytes, veja:



DB = Define Byte            -> aloca 1 byte

DW = Define Word           -> aloca 2 bytes

DD = Define Doubleword  -> aloca 4 bytes

DQ = Define Quadword    -> aloca  8 bytes

DT = Define Ten              -> aloca 10 bytes



Sabendo disso, poderemos agora mostrar como é a sintaxe de uma instrução em Assembly para alocar memória:

Nome_da_Variavel diretiva_define valor



Por exemplo, para alocar espaço para o caractere 'A', fazemos:

letra1 DB 'A'



Lembramos que, na verdade, embora tenhamos escrito o caractere 'A', tudo são números.

Então, como na tabela ASCII o valor de 'A', em hexadecimal é 41, poderíamos ter feito:

letra1 DB 41H



Colocamos a letra H ao final do número para dizer que estamos representando em Hexadecimal.

Se fossemos colocar em binário, temos que colocar a letra B ao final:

letra1 DB 01000001B



Para saber mais sobre os caracteres em programação, consulte nosso artigo do site C Progressivo, que também mostra a tabela ASCII:

http://www.cprogressivo.net/2012/12/O-tipo-char-como-escrever-textos-na-linguagem-C.html



Um pouco de matemática

Em Assembly, trabalhamos sempre com bytes, onde um byte equivale a 8 bites.

Cada bit desse pode ser 0 ou 1, então podemos representar até: 2^8 = 256 caracteres com um byte.



Em Hexadecimal, podemos representar esses 256 caracteres usando os números 00H até FFH.

Ou seja, 41H caberia em um byte, pois é menor que FFH.

Agora 2112H só caberia em dois bytes, onde um armazenaríamos o byte 12H e no outro o byte 21H.



Vamos armazenar uma senha na variável 'senha', ela conterá 4 dígitos decimais: 1234

Esse número, em hexadecimal equivalem a 4660H.

Precisamos, então, definir dois bytes, ou uma palavra (word). Um byte armazena o 60H e o outro armazena o 46H.

Para alocar memória para essa senha, faríamos:

senha DW 466H



Outras maneiras de alocar memória em Assembly

E se quiséssemos alocar uma palavra, como 'curso', por exemplo?

Poderíamos alocar letra por letra:

letra1 DB 'c'

letra2 DB 'u'

letra3 DB 'r'

letra4 DB 's'

letra5 DB 'o'



Porém, seria muito trabalhoso, e há maneira mais fáceis de se fazer isso.

Em vez de ter que dar um nome para cada letra (isso não faz o menor sentido!), poderíamos dar um nome só para o conjunto de letras:

curso DB 'c'

DB 'u'

  DB 'r'

  DB 's'

  DB 'o'



E sempre que usarmos a variável curso, o Assembly saberá que se trata de conjunto de caracteres.

Porém, esse exemplo, assim como o anterior, tem mais caráter de informação para você, leitor de nosso curso Assembly Progressivo.



A maneira mais prática e utilizada para armazenar uma string, é utilizando a define DB e escrevendo uma string (que nada mais é que um texto, um conjunto de caracteres).

O Assembly irá alocar, automaticamente, todos os caracteres, como se tivéssemos feito o exemplo passado.



No exemplo do "Hello, world" em Assembly, nosso primeiro programa, fizemos isso:

helloWorld DB 'Curso Assembly Progressivo: online, gratis e completo'



Bem mais prático, não?



Reservando memória em Assembly

Até agora, usando a diretiva define e suas variações (DB, DW, DD, DQ e DT), alocamos memória em Assembly para armazenar e INICIALIZAR variáveis! Porém, nem sempre vamos inicializar, apenas queremos alocar.

Isso é comum para armazenar variáveis cujos valores serão fornecidos posteriormente, pelo seu programa, pelo usuário ou um dispositivo de entrada e saída.



Para reservar memória, usamos a diretiva RES, ao mesmo molde da diretiva DEFINE:

RESB = Reserve Byte             -> reserva 1 byte

RESW = Reserve Word            -> reserva 2 bytes

RESD = Reserve Doubleword   -> reserva 4 bytes

RESQ = Reserve Quadword     -> reserva 8 bytes

REST = Reserve Ten               -> reserva 10 bytes



A sintaxe é um pouco diferente da DEFINE, já que não vamos inicializar.

Assim, em vez de valor inicial, temos que dizer quanto de espaço queremos reservar, dependendo da diretiva que usamos.

Sintaxe para reservar memória:

nome_da_variavel diretiva_res numero_de_unidades



Por exemplo:

variavel1 RESB 1 ; nesse caso, reservamos apenas 1 byte

variavel2 RESB 2 ; aqui, reservamos 2 bytes

variavel3 RESW 3 ; 3 palavras são reservadas, o que nos dá 3*2 = 6 bytes

variavel4 REST 10 ; reservamos 10 unidades, de 10 bytes cada

4 comentários:

Unknown disse...

Boa tarde, eu não entendi como 1234 em decimal se torna 4660H, como eu chego ah esse número em Hexadecimal? eu utilizei uma calculadora para conversão e não obtive o mesmo resultado.

Não sei disse...

É a representação em ASCII

Harli disse...

Na verdade ele inverteu, esse 1234 esta em hexa e 4660 em decimal.

Duelo Digital disse...

Use a calculadora do windows no modo desenvolvedor , não sei se os valores.batem mas lá é possível converter de boa

Veja também: