Este documento está em construção
Com o objetivo de criar um SDK em assembly voltado pra
retro computação usando como base o estilo de código do NASM,
facilitando a migração de novos usuários que vem do x86 para
processadores 8 bits.
| Ferramenta |
Descrição |
| HC Assembler |
Assembler com estrutura e estilo de código
baseado no NASM |
| HC Linker | Vinculador de objetos e gerador de
executáveis a partir de objetos e bibliotecas |
| HC Builder |
Gestor de Projetos, responsável por compilar
e limpar arquivos de saída do projeto |
| HC Librarian |
Gestor de Bibliotecas, que são conjuntos de
objetos que podem ser referenciados por um projeto |
| Download para navegadores que não suportam javascript |
| Download para navegadores que suportam javascript |
Assembler compatível com o estilo do NASM.
Tanto o código fonte quanto o binário gerado são compostos por
seções, sendo estas:
As seções são independentes e seu conteúdo é agrupado
sequencialmente na ordem que é definido no arquivo, então mesmo
que se defina o conteúdo das seções de forma intercalada e
misturada, o resultado sempre será agrupado pela sua seção.
O código fonte em assembly é composto por alguns blocos de
informações distintos:
Os comandos aceitam como argumentos valores
no formato suportado pelo assembler.
Todos os tópicos listados acima serão explicados com mais
detalhes posteriormente
Exemplo:
| ; comentário, ao final de qualquer linha de
código é aceito comentário cujo a identificação é o seu
caractere inicial ponto e virgula ';' seguido por texto
livre até o final da linha atual mov ax, bx ; exemplo de mnemônico (comando da CPU) e seus argumentos xpto: ; exemplo de rótulo simples com comentário (este) xpto2: mov bx, cx ; exemplo de rótulo com comando mnemônico (podendo ser um comando do assembler) e comentário db 0, 1, 2 ; exemplo de comando do assembler, em sintaxe é idêntico a um comando mnemônico |
Para cada arquitetura suportada é disponibilizado um executável
do assembler, com o nome iniciado em "hcasm-" seguido do
processador suportado.
Exemplo para compilar um código para Z80 (arquivo.s) em um objeto
(arquivo.obj):
| hcasm-z80 -o arquivo.obj arquivo.s |
Existem 2 tipos de rótulos:
Opcionalmente para melhor identificação, a definição de um rótulo
pode ser seguido do caractere ':' como marcador separador entre o
rótulo e o próximo comando do tipo mnemônico/assembler, porém no
caso do uso do nome de rótulo como uma referência a um rótulo
existente, é vedado o uso do caractere ':'.
Qualquer rótulo que não esteja presente no arquivo atual porem
seja referenciado nele, será automaticamente considerado como se
viesse de outro objeto, e será tratado pelo HC Linker.
Exemplo (Código Intel 8086/8088):
| global primario1
; exporta o rótulo primario1 para uso em outros objetos,
será tratada as suas referencias automaticamente pelo HC
Linker primario1: ; este é um rótulo primario .secundario1: ; este é um rótulo fica dentro do primario1, podendo ser acessado dentro do primario1 pelo seu nome direto (.secundario1) ou de fora do rotulo primario1 usando o nome composto de primario1.secundario1primario2: ; este é o segundo rótulo primário do arquivo, a partir daqui todos os rótulos secundários dos rótulos primários anteriores deixam de ser acessíveis com seus nomes diretos .xpto: ; este rótulo é o primeiro rótulo secundário de dentro do primario2, podendo ser acessível como .xpto de dentro do primario2 ou primario2.xpto de qualquer parte do arquivo |
Toda constante é declarada como um rótulo, seguindo as mesmas
regras destes. (Ver Rótulos)
O que diferencia um rótulo de uma constante é que ao invés de
conter o ponteiro para aquela posição no código fonte/binário,
contém um valor pré-definido.
As constantes podem tanto ser nós secundários como primários de
outras constantes ou rótulos, não havendo distinção de seu uso em
código fonte, porém as constantes não são suscetíveis ao calculo
de realocação, sendo úteis para referencias fixas na memória.
Para declara uma constante basta, declarar um rótulo e na mesma
linha a seguir do rótulo usar o marcador 'equ' seguido da equação
desejada.
Exemplo:
estrutura_pessoa: equ
11 ; sugestão de uso: o rotulo primario como
estrutura, contendo o tamanho da estrutura.nome: equ 0 ; sugestão de uso: no caso de uma estrutura os campos contém o seu desvio a partir do inicio da estrutura, por exemplo o campo nome, é o primeiro campo, assim contém o desvio de 0 bytessection data ; define que o código a partir dessa linha pertence a seção de dados obj_pessoa: resb estrutura_pessoa ; exemplo da reserva do objeto do tipo estrutura_pessoa, utilizando a constante que armazena o tamanho da estrutura section text ; define que o código a partir dessa linha pertence a seção de texto(código fonte) mov si, obj_pessoa ; exemplo de uso indireto dos campos mov al, [si + estrutura_pessoa.idade] ; exemplo de leitura de um campo indireto, usando um ponteiro (registrador SI) mov al, [obj_pessoa + estrutura_pessoa.idade ; exemplo da leitura do campo diretamente sem uso de ponteiros |
Como argumento dos comandos são aceitos valores nos seguintes
formatos:
Ao serem usados como argumentos, estes devem ser separados por
vírgula.
Exemplo (em 8086/8088):
| const_teste equ 10 ;
registra uma constante para uso no código mov ax, 123 ; define um valor simples para um registrador mov bx, 123 + 23 ; define um valor composto de uma expressão matemática para um registrador mov cx, [rotulo] ; lê o conteúdo de um rótulo para um registrador mov dx, [rotulo + const_teste - 3] ; lê o conteúdo de um endereço calculado por uma expressão matemática contendo rótulos, constantes e valores para um registrador mov si, rotulo ; define um ponteiro para um rótulo em um registrador mov ax, [si] ; lê o conteúdo do ponteiro anteriormente definido em um registrador mov ax, [si+const_teste] ; lê o conteúdo de um ponteiro com um desvio calculado por uma expressão matemática para um registrador rotulo: ; registra um rotulo para uso no codigo db "string de teste",0 ; emite o binário de uma string seguida do valor numérico zero db 0b10101010 ; emite um byte db 0x99 ; emite um byte |
Para auxiliar o desenvolvimento o assembler suporta vários
comandos básicos baseados nos equivalentes do NASM.
Este comando emite binario diretamente para o arquivo de saída,
podendo ser usado apenas nos segmentos TEXT e DATA.
Os bytes(db) ou words(dw) são emitidos conforme a sequência de
números informados como argumentos do comando.
Não há limitação de quantidade de argumentos, e estes podem ser
numéricos ou strings.
| db 0x12, 0x34, 0x56
; no arquivo de saída emitirá nessa posição os bytes de
valor 0x12 seguido do 0x34 e do 0x56 dw 0x1234, 0x5678 ; no arquivo de saída emitirá nessa posição os bytes(as words são convertidas em bytes no formato little endian): 0x34, 0x12, 0x78, 0x56 db "ABC",0 ; no arquivo de saída emitirá nesta posição os bytes: 0x41 0x42 0x43 0x00 |
Este comando reserva um espaço vazio no arquivo de saída.
As reservas de bytes(rb ou resb) ou words(rw ou resw) são feitas
conforme a quantidade informada no seu argumento.
| rb 10 ; no
arquivo de saída reservará 10 bytes na posição atual rw 10 ; no arquivo de saída reservará 10 words(20 bytes) na posição atual resb 10 ; no arquivo de saída reservará 10 bytes na posição atual |
Este comando repete o conteúdo que vem a seguir dele um numero
definido de vezes no arquivo de saída
| times 5 db 0x12
; emite no arquivo de saída 123 vezes seguidas o byte 0x12,
ficando: 0x12 0x12 0x12 0x12 0x12 times 510-$ db 0 ; emite no arquivo de saída bytes de valor 0 até preencher o que falta para a posição 510, exemplo se o binário estiver já contendo 500 bytes, ele preencherá os 10 faltantes com 0 times 3 db "AB" ; emite no arquivo de saída 3 vezes o conteúdo em binário equivalente a string "AB" ficando: 0x41 0x42 0x41 0x42 0x41 0x42 times 3 nop ; emite o comando mnemônico nop 3 vezes no binário de saída |
Altera a seção atual da saída, permitindo intercalar várias
seções de saída no mesmo arquivo.
Seções suportadas: text, data, bss*
* A seção BSS não suporta nenhum comando que gere dados
binários, podendo usar apenas comandos que reservem espaços e
rótulos de todos os típos
| section text ;
altera a seção atual para text nop ; comando gerado dentro da seção text section data ; altera a seção atual para data nop ; comando gerado dentro da seção data section bss ; altera a seção atual para bss rb 123 ; comando reservando espaço na seção bss |