Curso de Assembly
Usando o Macro Assemblador RSC II
Você está em: MarMSX >> Cursos >> Assembly Z80
O macro-assemblador RSC II, criado pelos espanhóis da RSC SOFTWARE, é uma poderosa ferramenta para aqueles que desejam programar em Assembly. Ela é bem fácil de se utilizar, pois se assemelha muito com o ambiente do BASIC do MSX, além de possuir diversas ferramentas para depuração para o seu programa.
Além disso, a ferramenta possui total interação com o BASIC, uma vez que é possível sair dela, ir ao BASIC e testar seu programa, e depois voltar ao RSC II com o programa fonte ainda intacto na memória.
Um assemblador tem como por objetivo converter os códigos mnemônicos para linguagem de máquina. O ambiente RSC II possui:
- Um editor de código mnemônico nos moldes do Basic do MSX.
- O recurso de ETIQUETAS (LABELS), que são nomes que substituem endereços de memória. Por exemplo, CALL WRTVRM em vez de CALL &H4D.
- Os PSEUDO-COMANDOS, que auxiliam passar dados para a memória. Por exemplo, para colocarmos uma string na memória, utilizamos o pseudo-comando: DEFM "O MSX é fácil programar".
1. Estrutura de um programa Assembly
Linha
| Etiqueta
| Instrução
| Comentário
|
10
20
30
40
50
|
Soma: |
LD A,B
LD C,20
ADD A,C
RET NZ
JR SOMA |
; Carrega A com B
; Carrega C com 20
; Soma A com C
; Retorna se A<>0 |
Cada linha comporta exatamente uma instrução em Assembly.
A etiqueta serve para substituir um endereço de memória, que pode ser estático ou dinâmico. Ele é estático quando definimos um valor fixo para ele. Exemplo:
10 WRTVRM: EQU &H4D
Assim, a etiqueta WRTVRM será sempre o valor de memória &H4D.
Uma etiqueta possui endereço dinâmico quando utilizada para referenciar uma instrução, conforme a etiqueta "Soma" referencia a instrução "LD A,B" no programa acima. Dessa forma, o valor da etiqueta depende do endereço que se localizar a instrução "LD A,B", que é calculada quando o Assemblador converte o código para linguagem de máquina.
Uma etiqueta é sempre seguida do sinal de dois pontos ":".
Os comentários são opcionais e servem para explicar partes do código. O sinal de ponto e vírgula ";" indica que a partir dali, tudo é comentário na linha corrente.
As instruções são os códigos mnemônicos que serão convertidos para linguagem de máquina. Elas são o que realmente interessam para o Assembler.
2. Começando a programar
No disco virtual do curso, está o RSC II.
Vá para o Basic, digite:
BLOAD"RSCII.BIN",R ↵
O visual dele lembra muito o ambiente do Basic do MSX, entretanto, estamos no ambiente do RSCII. Dessa forma, não irão funcionar aqui os comandos do Basic.
Para começar a programar, digite IN e tecle "Enter". O comando IN equivale ao AUTO do Basic.
Digite o seguinte programa:
10 ORG &HC000
20 WRTVRM: EQU &H4D
30 LD A,&H41
40 LD HL,0
50 LD B,&H80
60 INICIO: CALL WRTVRM
70 INC HL
80 INC A;
90 CP B
100 JP NZ,INICIO
Tecle CONTROL+STOP para sair da digitação do programa.
Antes de convertermos para LM, vamos salvar o código fonte. Para isso, digite:
GT "exerc1.asm" ↵
A extensão ".ASM" é muito utilizada para os fontes em Assembly no MSX.
Se você necessitar carregar o programa salvo, digite:
CT "exerc1.asm" ↵
O comando LT serve para listar o programa em Assembly. Ele possui a mesma sintaxe que o LIST do Basic. Assim:
LT ; Lista todo o programa.
LT 10 ; Lista a linha 10.
LT 20-30 ; Lista da linha 20 à 30.
; Stop pausa a listagem e espaço continua.
Agora, o código fonte apresentado será assemblado (convertido para LM). Para isso, digite EN e tecle enter. Digite a opção 3 e em seguida a opção H (hexadecimal).
EN ↵
No. de Opción: 3 ↵
Modo (H/D): H ↵
A tecla "Stop" dá uma pausa na listagem e "Espaço" continua a listar.
O programa enfim é transformado em LM e o Assemblador informa se houve erros.
RSC II MSX 1.0
C000 10 ORG &HC000
004D 20 WRTVRM: EQU &H4D
C000 3E41 30 LD A,&H41
C002 210000 40 LD HL,0
C005 0680 50 LD B,&H80
C007 CD4D00 60 INICIO: CALL WRTVRM
C00A 23 70 INC HL
C00B 3C 80 INC A
C00C B8 90 CP B
C00D C207C0 100 JP NZ,INICIO
Etiquetas ausentes: 0
Errores detectados: 0
-----------------------------------------------
Etiquetas - Macros:
WRTVRM: 77 - 004D
INICIO: 49159 - C007
A primeira coluna marca o endereço inicial de cada instrução, enquanto que a segunda contém o código em LM de cada instrução.
O programa vai de &HC000 até &HC00F, pois a última instrução possui 3 bytes.
Só podemos salvar o código binário (LM) depois que assemblarmos (EN) o código fonte. Anote os endereços iniciais e finais do programa, para indicar ao comando GB, que faz a gravação dos dados binários. Salve usando:
GB"exerc1.bin",&hC000,&HC00F
2.1. Rodando um programa em LM
Após assemblar o programa, há três opções para rodá-lo:
- Copiar o código em LM e executá-lo a partir do Basic.
- Ir para o ambiente Basic e executar o código que já está na memória.
- Salvar o código em um arquivo binário e depois executá-lo a partir do Basic.
Para a primeira opção, anote o código em LM e digite um programa em Basic para carregar o código na memória e executá-lo:
10 FOR E=&HC000 TO &HC00F
20 READ A$
30 POKE E,VAL("&H"+A$)
40 NEXT E
50 DEFUSR=&HC000
60 X=USR(0)
100 DATA 3E,41,21,00,00,06,80,CD,4D,00,23,3C,B8,C2,07,C0
Para a segundo, basta ir ao Basic, digitando BA. No Basic, digite:
DEFUSR=&HC000 ↵
Ok
X=USR(0) ↵
Para a terceira, no Basic, digite:
BLOAD"exerc1.bin",R ↵
2.2. O simulador do RSC II
Que tal agora usarmos o simulador do RSCII? Ele serve para executarmos instrução a instrução e visualizarmos o resultado em cada registrador do Z80.
Para iniciar o simulador, utilize o comando SI seguido do endereço inicial do programa.
Mas antes, vamos criar um programa mais simples para observar seu funcionamento.
10 ORG &HC000
20 LD A,5
30 LD B,4
40 ADD A,B
50 RET
Esse programa carrega o valor 5 no registrador A e depois o valor 4 no registrador B. Então, faz a soma entre os registradores A e B e coloca o resultado em A.
Assemble com EN e depois digite:
SI &HC000 ↵
Modo (H/D): H ↵
Saída:
Slot: 11111111 I R P C
00000000 0028 C000
A B C D E H L I X I Y SZ H PNC
00 . 0000 0000 0000 0000 0000 00000000
00 . 0000 0000 0000 00000000
SP: FAE0
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
41 A 41 A 41 A 41 A 41 A 0000
55 U 55 U 55 U 55 U 55 U FAE0
C000 3E05 LD A,&H05
Registradores:
A B C D E H L I X I Y SZ H PNC
00 . 0000 0000 0000 0000 0000 00000000 <--- Normais
00 . 0000 0000 0000 00000000 <--- Linha
Próxima instrução:
C000 3E05 LD A,&H05
Importante: o estado dos registradores no simulador é um estado IMEDIATAMENTE ANTES da execução da próxima instrução. Assim, no exemplo apresentado, o estado dos registradores é anterior à execução da instrução LD A,&H05. Essa instrução somente afetará o registrador A, após a sua execução.
Os comandos básicos para o simulador são:
- E= Executa a linha apontada por PC.
- S= Salta linha atual (não executa) para a próxima instrução.
- M= Permite alterar os registradores. Navegue com as setas e valide com "Return" primeiro a linha dos registradores normais, depois a dos registradores linha.
- O= Altera SP e PC.
Vamos executar a primeira instrução? Tecle "E" para isso. Resultado:
Slot: 11111111 I R P C
00000000 0028 C002
A B C D E H L I X I Y SZ H PNC
05 . 0000 0000 0000 0000 0000 00000000
00 . 0000 0000 0000 00000000
SP: FAE0
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
41 A 41 A 41 A 41 A 41 A 0000
55 U 55 U 55 U 55 U 55 U FAE0
C002 0604 LD B,&H04
Após a execução da instrução LD A,&H05, o registrador A é alterado. Além disso, PC passa para a próxima instrução. As mudanças ocasionadas pela instrução executada são destacadas em verde.
Terceiro passo (tecle "E" novamente):
Slot: 11111111 I R P C
00000000 0028 C004
A B C D E H L I X I Y SZ H PNC
05 . 0400 0000 0000 0000 0000 00000000
00 . 0000 0000 0000 00000000
SP: FAE0
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
41 A 41 A 41 A 41 A 41 A 0000
55 U 55 U 55 U 55 U 55 U FAE0
C004 80 ADD A,B
Após a execução da instrução LD B,&H04, o registrador B é alterado. PC passa para a próxima instrução.
Quarto passo:
Slot: 11111111 I R P C
00000000 0028 C005
A B C D E H L I X I Y SZ H PNC
09 . 0400 0000 0000 0000 0000 00000000
00 . 0000 0000 0000 00000000
SP: FAE0
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
00 . 00 . 00 . 00 . 00 . 0000
41 A 41 A 41 A 41 A 41 A 0000
55 U 55 U 55 U 55 U 55 U FAE0
C005 C9 RET
Após a execução da instrução ADD A,B, o registrador A é alterado. PC passa para a próxima instrução.
Ao clicar novamente em "E", o simulador encontra a instrução RET e termina. Podemos também interromper o simulador a qualquer tempo teclando CONTROL+STOP.
Dica: utilize somente o RSC II para testar o funcionamento programa, sem as chamadas às sub-rotinas da ROM, uma vez que isso poderá travar o RSCII.
3. Os pseudo-comandos do RSC II
Pseudo- comando |
Sintaxe |
Exemplo |
Função |
ORG |
ORG x1 |
ORG &HD000 |
Define endereço para inserir instruções. |
DEFB |
DEFB x1,x2,...,xn |
DEFB 1,2,&HCD |
Insere o valor do byte na memória. |
DEFM |
DEFM "<cadeia>" |
DEFM "Maracana" |
Insere uma string na memória. |
DEFW |
DEFW x1,x2,...,xn |
DEFW &HCD00 |
Insere de dois em dois bytes (word). |
DEFS |
DEFS n |
DEFS 40 |
Insere na memória n bytes com o valor 0. É uma reserva de espaço. |
EQU |
<nome>:EQU <end> |
INI: EQU &H00CD |
Define uma etiqueta com um valor concreto. |
END |
END |
END |
Termina o programa. |
MAC |
<nome>:MAC |
MULTI:MAC |
Define o inicio de uma macro. |
ENDM |
ENDM |
ENDM |
Define o final de uma macro. |
IF |
IF x1 |
IF |
Marca o inicio do trecho do programa, que será assemblado somente se x1 for verdadeiro. |
ENDI |
ENDI |
ENDI |
Dá finalidade à condição IF |
4. Considerações finais
Após se familiarizar com o RSC II, o leitor poderá utilizá-lo para testar os comandos Z80 do próximo capítulo, bem como revisar o capítulo anterior.
Este tutorial é um breve tutorial sobre o RSCII. Se você deseja um tutorial mais aprofundado sobre o RSCII, clique aqui.
O manual do RSC II foi traduzido ao português e se encontra no tutorial do RSCII.