ENDEREÇOS DE MEMÓRIA

Creio que deveria ter feito este tutorial antes, pois considero de extrema importância na hora de decifrar algorítmos em assembly. Trata-se do uso dos endereços de memória.

Antes de iniciar, vou fazer uma diferenciação entre os registradores e os endereços de memória. Os registradores são pequenas partes de memória do processador, para armazenamento temporário de dados. Nos computadores mais comuns ( x86 ), eles armazenam valores de 32 bits ( 4 bytes ) e são usados basicamente para calculos simples durante o tempo de execução do programa. Já a memória fica responsável por armazenar grande quantidade de dados, como textos ( strings ).

Vamos ao assunto principal.

Veja no código abaixo:

00401000 B9 05000000 MOV ECX,5
00401005 BE 04304000 MOV ESI,pont.00403004 ; ASCII "abcde"
0040100A BF 0C304000 MOV EDI,pont.0040300C
0040100F 49 DEC ECX
00401010 8B1C31 MOV EBX,DWORD PTR DS:[ECX+ESI]
00401013 891F MOV DWORD PTR DS:[EDI],EBX
00401015 47 INC EDI
00401016 0BC9 OR ECX,ECX
00401018 77 F5 JA SHORT pont.0040100F

O primeiro comando, move o valor 5 para o recistrador ECX
Na segunda linha ( MOV ESI,pont.00403004 ), o que está acontecendo? Ele está movendo para o registrador ESI o valor 00403004, que o Olly já identifica como sendo um endereço da memória do programa, por isso adicionou o "pont.00403004". O Olly também já identificou que esse endereço aponta para o primeiro byte da string "abcde", como mostra a tabela abaixo:

Endereço Conteúdo ( ASCII )
00403004 a ( 97 )
00403005 b ( 98 )
00403006 c ( 99 )
00403007 d ( 100 )
00403008 e ( 101)

Analisando o código, vemos que ESI então aponta para 403004 ( início da string "abcde" ) e EDI aponta para 40300C, que é um espaço de memória vazio, não inicializado ainda. Em seguida ele decrementa o valor de ECX, que até então era 5 e passa a ser 4. Na próxima linha vem a parte principal deste tutorial.

00401010 8B1C31 MOV EBX,DWORD PTR DS:[ECX+ESI] ; sentenca 1

Esse "DWORD PTR" indica que EBX está recebendo o conteúdo do endereço que está sendo apontado ( ECX+ESI ). Releia essa frase quantas vezes forem necessárias. O valor que fica entre colchetes indica o endereço, que no caso é ECX+ESI. Alguns parágrafos acima vimos que ECX é 4 e ESI continha o valor 00403004, que era o primeiro byte da string "abcde". Somando os 2 valores temos: 00403004 + 4 = 00403008. Agora as coisas estão ficando mais claras. EBX então está recebendo o conteúdo do endereço de memória 00403008. Se você olhar na tabela acima, verá que esse conteúdo corresponde a letra "e" ( 101 ). Em outras palavras, EBX = 101.

Avançando uma linha temos:

00401013 891F MOV DWORD PTR DS:[EDI],EBX ; sentenca 2

Creio que agora ficou mais fácil de entender o que está acontecendo. EDI aponta para um local de memória vazia ( como vimos no início ), cujo endereço é 0040300C. Esse endereço de memória recebe o valor de EBX ( 101 ). Resumindo, o local de memória 0040300C contém o número 101.

Mas o que aconteceria se eu tivesse apenas "MOV EDI, EBX"? Neste caso você faria com que EDI recebesse o valor de EBX. No entanto, o que você quer fazer é mover o valor de EBX para o endereço que o EDI está apontando.

Em seguida ele incrementa EDI ( EDI++ ). EDI continha o valor 0040300C e agora passa a ser 0040300D. Na próxima linha ele realiza uma operação lógica OR com ECX ( 4 ) para verificar se ECX é nulo. Se não for, ele repete o processo, mas com valores alterados. Na segunda iteração ( segunda repetição ), ECX é novamente decrementado, passando de 4 para 3. A soma ECX+ESI, ao invés de ser 00403004 + 4, vai ser 00403004 + 3, que corresponde ao endereço do caractere "d" ( 100 ). Esse valor é armazenado no endereço apontado por EDI, que agora é 0040300D.

Voce já deve ter entendido o que o algorítmo faz. Caso não tenha percebido, ele simplesmente inverte uma string, colocando o resultado em um local de memória. Aí vai uma figura para ajudar ( lembrando que o processo começa movendo o conteúdo de 403008 para 40300C ).

Espero ter ajudado a esclarecer um pouco sobre essa questão de endereços de memória. Até a próxima!

F3rGO!