Bin.smwcentral.net
ASM B?SICO E CODIFICA??O DE BLOCOS PARA O GOPHER POPCORN STEW (GPS)Por Manuz, major Flare(a.k.a Fierce Deity Manuz OW Hacker)PARTE 1 – ASM (assembly) B?SICO0. Introdu??o à linguagem 65c816 assemblyEste tutorial destina-se, de forma geral, à aprendizagem, da forma mais intuitiva que eu possa apresentar, da linguagem assembly 65c816, própria para a plataforma SNES. A linguagem assembly possui muitas peculiaridades, fazendo-a diferente de linguagens como C e C++: é uma linguagem de baixo nível, tornando-se, portanto, de difícil entendimento. Porém, com uma intui??o básica da abordagem top-down de programa??o, muitas vezes fica menos difícil programar em assembly. Esse tutorial tentará direcionar os algoritmos montados nessa abordagem.A linguagem assembly é uma tradu??o quase “direta” da linguagem de máquina que o processador (no caso, o SNES) entende. Ela é composta de vários símbolos simples, que formam as instru??es. Aqui, trataremos cada instru??o (ou conjunto) de modo separado, de forma a enfatizar certos aspectos importantes que afetam o andamento do código.Para facilitar a leitura do tutorial, a partir de agora a linguagem assembly 65c816 será identificada apenas como ASM.1. Revis?o básica das principais bases numéricasComo qualquer outra linguagem, o ASM permite a manipula??o de dados em bases numéricas n?o-decimais. Como é uma linguagem de nível diretamente acima do código de máquina, as bases mais comuns de trabalho s?o a hexadecimal (base 16) e a binária (base 2).Antes de mais nada, base numérica apenas interfere em como um dado é representado. Por exemplo, o número 60 é representado por 60 na base decimal, 3C na base hexadecimal e 0011 1100 na base binária (em representa??o de 8-bits). A principal característica que diferencia uma base numérica da outra é a quantidade de algarismos que podem representar o número. Na base decimal, usamos 10 algarismos (0 até 9). Na base binária, usamos apenas os algarismos 0 e 1. E, na base hexadecimal, usamos 16 algarismos (0 até 9 e as letras A até F). A tabela a seguir mostra a convers?o dos 16 primeiros números nas 3 possíveis bases:HexadecimalBinário (4 bits)Decimal000000100011200102300113401004501015601106701117810008910019A101010B101111C110012D110113E111014F111115Tabela 1. Principais bases numéricas para os 16 primeiros algarismos.No ASM, esses valores, quando constantes, ser?o representados utilizando-se símbolos diferentes, que ser?o tratados ao decorrer do tutorial. Para se evitar problemas, recomendo a utiliza??o da Calculadora do Windows (ou outro aplicativo) para a convers?o entre essas bases.2. Os 3 registradores de uso geral e (quase) livre do ASMSendo um processador, o SNES possui registradores, que s?o entidades digitais onde certos valores s?o armazenados de forma a permitir ao processador realizar o conjunto de instru??es que lhe é passado. Existem pelo menos 9 registradores no SNES, mas alguns s?o de propósitos específico. Para esse come?o de tutorial de ASM, vou focar em 3 registradores que s?o de uso comum: o registrador Acumulador (A) e os registradores de ?ndice, representados por X e Y. Os 3 s?o registradores de 16-bit, mas s?o normalmente usados no modo 8-bit. Em outras palavras: embora você possa, teoricamente, carregar valores entre 0 e 65535 nesses registradores, você usará, em pelo menos 90% dos casos, apenas os valores entre 0 e 255. Nessa parte básica, vamos utilizar 8 bits no come?o e o registrador Acumulador. O registrador A é o mais importante da lista. Nele s?o carregados valores, esses valores s?o trabalhados (por meio de opera??es matemáticas) e salvos na memória. Praticamente n?o há código feito sem o uso desse registrador.Já os registradores de índice, X e Y, s?o úteis principalmente para criar algoritmos baseados em arrays, ou vetores (conceito tirado do C). Falarei deles mais adiante, quando for preciso.3. A memória (parte 1): memória RAM e memória ROMRAM significa Random Access Memory. ? uma memória que pode ser tanto lida quanto escrita. No SNES, ela corresponde a um intervalo de endere?os. Já ROM significa Read-Only Memory. ? uma memória que apenas pode ser lida. Também corresponde a intervalos de endere?os no SNES.Basicamente, o SNES é mapeado byte por byte. Os endere?os s?o representados por números de 24 bits, e variam entre $000000 a $FFFFFF (note o símbolo ‘$’ – indicando valores em base hexadecimal). A memória RAM está mapeada entre os endere?os $7E0000 e $7FFFFF. Já a memória ROM é mapeada nos intervalos $xx8000 a $xxFFFF (em que xx pode ser qualquer valor hexadecimal entre 00 e 6F). Além disso, temos uma peculiaridade no SNES: na representa??o de endere?o da forma $xxyyyy, xx denota o banco de memória (bank). Nos bancos de 00 a 3F, os endere?os $xx0000 a $xx1FFF s?o especiais: eles s?o uma cópia das RAMs entre $7E0000 e $7E1FFF. Além disso, os endere?os $xx2000 a $xx7FFF s?o registradores de hardware, que executam tarefas específicas (DMA, VRAM, etc.). Para fins desse tutorial, n?o entrarei em maiores detalhes sobre outras áreas da memória do SNES. Para essa parte básica, a ROM e a RAM devem ser suficientes.4. Carregando e Guardando dados (parte 1) – LDA, STA, STZAgora, vamos dar início ao ASM propriamente dito. A coisa mais básica a ser feita é ler e escrever coisas na memória. Para isso, usaremos o registrador acumulador. Primeiramente, precisamos carregar um valor. Mas de onde carregar? Esse valor pode ser uma constante (chamada de imediato) ou um valor guardado em memória. Suponhamos que queremos guardar o valor $0A (em hexadecimal) na posi??o de memória da RAM dada pelo endere?o $7E13CC. O algoritmo básico seria:$7E13CC = #$0ANote a simbologia; coloquei um ‘#’ antes do $0A. Isso, no ASM, significa que o valor é uma constante, ou imediato; portanto, n?o precisa ser lido da memória. Note ainda que o algoritmo acima ainda está em um nível muito alto para o ASM; precisamos refiná-lo:Acumulador = #$0A$7E13CC = AcumuladorNote agora que o mesmo algoritmo foi quebrado em dois passos. Esses dois passos s?o elementares, e podem ser traduzidos cada um em uma única instru??o do nosso ASM. No caso acima, usaremos as instru??es LDA (Load to Accumulator) e STA (Store Accumulator). O algoritmo acima, utilizando-se essas instru??es, se traduz em:LDA #$0A ; Acumulador = #$0ASTA $7E13CC ; $7E13CC = AcumuladorAgora sim, temos um código ASM perfeitamente válido! Porém, note que podemos fazer uma simplifica??o: salvo em raríssimas exce??es (que est?o além desse tutorial, ent?o por ora n?o se preocupe), o 7E do endere?o RAM pode ser omitido, até para economizar espa?o. Isso só é possível por causa das cópias de RAM que existem nos bancos de $00 a $3F. Levando isso em considera??o, nosso peda?o de código final para o algoritmo proposto fica:LDA #$0A ; Acumulador = #$0ASTA $13CC ; $13CC = Acumulador ($7E13CC = Acumulador)Pronto, temos o primeiro algoritmo desse tutorial convertido para o ASM! N?o é t?o difícil quanto parece, certo? Agora, vamos tentar outro algoritmo: Suponha que queremos guardar o valor que está guardado em $7E0019 nas posi??es $7FB000 e $7E13CC, e que queremos zerar as posi??es de RAM $7E0088, $7E1491 e $7FB001. O algoritmo básico (alto nível):Carregar $7E0019 no AcumuladorGuardar o Acumulador em $7E13CC e em $7FB000Zerar $7E0088, $7E1491 e $7FB001Vamos come?ar a refinar o algoritmo, sabendo de uma coisa crucial: Opera??es de escrita em memória (com STA) n?o alteram o valor do acumulador! Refinando-se uma vez, temos:Acumulador = $7E0019$7E13CC = Acumulador$7FB000 = AcumuladorAcumulador = #$00$7E0088 = Acumulador$7E1491 = Acumulador$7FB001 = AcumuladorAgora, vamos fazer um 2? refinamento nesse algoritmo: Vamos simplificar os endere?os que comecem com $7E:Acumulador = $0019$13CC = Acumulador$7FB000 = AcumuladorAcumulador = #$00$0088 = Acumulador$1491 = Acumulador$7FB001 = AcumuladorAgora, o 3? refinamento: perceba que o primeiro endere?o está escrito como $0019. Esse endere?o pode ser simplificado mais uma vez! Agora, trataremos ele apenas como $19. Nesse caso, o endere?o lido é $0019, mas SEMPRE no banco $00. O mesmo vale para a RAM $0088 ($88). Ou seja, se você tem um endere?o RAM da forma $7E00xx, a simplifica??o para $xx SEMPRE é válida. N?o há exce??es. Vamos ao algoritmo:Acumulador = $19$13CC = Acumulador$7FB000 = AcumuladorAcumulador = #$00$88 = Acumulador$1491 = Acumulador$7FB001 = AcumuladorAgora, vamos fazer mais um refinamento, considerando o seguinte: Se seu endere?o é representado como $xx ou $xxxx (devido às simplifica??es), eu posso simplesmente zerá-lo sem precisar do acumulador. O algoritmo acima, refinado e estruturado, fica:Acumulador = $19$13CC = Acumulador$7FB000 = Acumulador$88 = 0$1491 = 0Acumulador = #$00$7FB001 = AcumuladorPronto, nosso algoritmo está composto de passos elementares e simples de serem traduzidos. Em ASM, fica:LDA $19 ; Acumulador = $19STA $13CC ; $13CC = AcumuladorSTA $7FB000 ; $7FB000 = AcumuladorSTZ $88 ; $88 = 0STZ $1491 ; $1491 = 0LDA #$00 ; Acumulador = #$00STA $7FB001 ; $7FB001 = AcumuladorNote que usamos outra instru??o: STZ (Store Zero). Essa instru??o simplesmente carrega o zero para uma determinada posi??o de memória. Muito mais rápida que uma sequência de LDAs e STAs. Porém, note que ainda precisei fazer algo assim no final do algoritmo, pois n?o existe STZ $xxxxxx. Simples assim.Até agora, temos as instru??es LDA, STA e STZ. A tabela a seguir mostra o que cada uma faz, dependendo do que for escrito (visto até agora e dois b?nus do LDA):Instru??oFuncionamentoLDA #$xxLê ‘xx’ (hexadecimal) em ALDA #xxLê ‘xx’ (decimal) em ALDA #%xxxxxxxxLê ‘xxxxxxxx’ (binário) em ALDA $xxLê a posi??o $0000xx em A (ou $7E00xx)LDA $xxxxLê a posi??o $yyxxxx em A ($7Exxxx, se yy estiver entre $00 e $3F, ou for $7E)LDA $xxxxxxLê a posi??o $xxxxxx em ASTA $xxGuarda A em $0000xx (ou $7E00xx)STA $xxxxGuarda A em $yyxxxx ($7Exxxx, se yy estiver entre $00 e $3F, ou for $7E)STA $xxxxxxGuarda A em $xxxxxxSTZ $xxZera o endere?o $0000xx (ou $7E00xx)STZ $xxxxZera o endere?o $yyxxxx ($7Exxxx, se yy estiver entre $00 e $3F, ou for $7E)Tabela 2. Usos básicos de LDA, STA e STZ (A: Acumulador)Deve-se notar, até agora, as seguintes coisas sobre as instru??es acima estudadas:- Jamais use STA em um endere?o que seja ROM. A ROM n?o pode ser escrita, apenas lida.- Como já mencionado, n?o existe STZ $xxxxxx.- N?o existe STA #$xxxx, STA #%xxxxxxxx, STA #xxxx ou similares. N?o faz sentido guardar uma valor em uma constante.Até aqui, já temos 3 instru??es e duas opera??es básicas do nosso ASM. Sabemos ler e escrever dados na memória, e zerar posi??es usando STZ. Agora, daremos prosseguimento ao estudo do ASM introduzindo outra classe de opera??es básicas: Opera??es matemáticas.5. Opera??es Matemáticas Básicas – CLC, ADC, SEC, SBC, INC, DEC, ASL e LSR ................
................
In order to avoid copyright disputes, this page is only a partial summary.
To fulfill the demand for quickly locating and searching documents.
It is intelligent file search solution for home and business.