Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .section .data
- #Autômato
- s1: # '%'
- .byte 2, 2, 5, 4, 5, -1, 7, 8, -1, 10, 12, 12, 13, 15, 15, 16, 18, 18, 19, 21, 21, 22
- s2: # ' '
- .byte 1, 2, 3, 4, 5, -1, 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
- s3: # '$'
- .byte 9, 2, 6, 4, 5, -1, 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
- s4: # ','
- .byte -1, 3, 3, 4, 5, -1, 7, 8, -1, 11, 11, 12, 14, 14, 15, 17, 17, 18, 20, 20, 21, 22
- s5: # '('
- .byte 19, 2, 4, 4, 5, -1, 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
- s6: # 'A-z'
- .byte 16, 2, 3, 4, 5, 8, 7, 8, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
- s7: # '0-9'
- .byte 22, 2, 3, 4, 5, 7, 7, 8, 13, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
- s8: # 'restante'
- .byte 1, 2, 3, 4, 5, -1, 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
- #Lista com o conjunto de instruções
- instrucoes: .asciz "movb|movw|movl|ret|int|jmp|je|jne|jle|jl|jge|jg|cmp|dec|inc|jnl|addl|subl|mull|pushl|popl|call|cpuid|bswap|divl|xchg|nop|cld|cmpsl|cmpsb|repe-cmpsb|rep-movsb|rep-movsl|movsb|movsl|imull|" #36 inst
- #Lista com o conjunto de registradores
- registradores: .asciz "eax|ecx|edx|ebx|esp|ebp|esi|edi|ax|cx|dx|bx|sp|bp|si|di|al|cl|dl|bl|ah|ch|dh|bh|"
- #Padrões de hexas para cada instrução e seus respectivos tamanhos
- padraoCaso1: .byte 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0xc3, 0xFF,0xFF,0xFF,0xFF,0xFF, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x0f,0xa2,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x90,0,0,0,0,0, 0xfc,0,0,0,0,0, 0xa7,0,0,0,0,0, 0xa6,0,0,0,0,0, 0xf3,0xa7,0,0,0,0, 0xf3,0xa4,0,0,0,0, 0xf3,0xa5,0,0,0,0, 0xa4,0,0,0,0,0, 0xa5,0,0,0,0,0 #35
- tamCaso1: .byte 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1
- padraoCaso2: .byte 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x48,0,0,0,0,0, 0x40,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0xf7,0xe0,0,0,0,0, 0xff,0xf0,0,0,0,0, 0x8f,0xc0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x0f,0xc8,0,0,0,0, 0xf7,0xf0,0,0,0,0
- tamCaso2: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 2, 2, 2, 0, 0, 2, 2
- padraoCaso4: .byte 0x88,0,0,0,0,0, 0,0,0,0,0,0, 0x89,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x39,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x83,0,0,0,0,0 #26
- tamCaso4: .byte 2, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 #26
- padraoCaso5: .byte 0x88,0xc0,0xFF,0xFF,0xFF,0xFF, 0x89,0xc0,0xFF,0xFF,0xFF,0xFF, 0x89,0xc0,0xFF,0xFF,0xFF,0xFF, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x39,0xc0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x01,0xc0,0,0,0,0, 0x29,0xc0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x83,0xc0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x0f,0xaf,0xc0,0,0,0
- tamCaso5: .byte 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 #36
- padraoCaso12: .byte 0x8a,0,0,0,0,0, 0x8b,0,0,0,0,0, 0xb8,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0
- tamCaso12: .byte 5, 5, 1, 0, 0
- padraoCaso13: .byte 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0xcd,0x80,0xFF,0xFF,0xFF,0xFF
- tamCaso13: .byte 0, 0, 0, 0, 2
- padraoCaso15: .byte 0xc6,0,0,0,0,0xFF, 0xc7,0,0,0,0,0xFF, 0xb8,0,0,0,0,0xFF, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x81,0xf8,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x81,0xc0,0,0,0,0, 0x81,0xe8,0,0,0,0
- tamCaso15: .byte 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 2
- padraoCaso16: .byte 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, /*Saltos:*/0xe9,0,0,0,0,0, 0x0f,0x84,0,0,0,0, 0x0f,0x85,0,0,0,0, 0x0f,0x8e,0,0,0,0, 0x0f,0x8c,0,0,0,0, 0x0f,0x8d,0,0,0,0, 0x0f,0x8f,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x0f,0x8d,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0xe8,0,0,0,0,0
- tamCaso16: .byte 6, 6, 6, 6, 6, /*Saltos:*/ 1, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1
- padraoCaso18: .byte 0x8a,0,0,0,0,0, 0x8b,0,0,0,0,0, 0x8b,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0
- tamCaso18: .byte 2, 6, 2, 6, 6
- padraoCaso21: .byte 0x8a,0,0,0,0,0, 0x8b,0,0,0,0,0, 0x8b,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x39,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0x83,0,0,0,0,0
- tamCaso21: .byte 2, 2, 2, 6, 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 #26
- #Dados padrões para o cabeçalho do ELF
- elfheader: .byte 0x7F, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 1, 0, 0, 0, /*Entrypoint:*/ 0x74,0x80,0x04,0x08, 0x34,0,0,0, /*Início do section header:*/0x0,0,0,0, 0,0,0,0, 0x34,0, 0x20,0, 0x2,0, 0x28, 0, 0, 0, 0, 0 #52 caracteres
- #Progam headers do ELF com alguns valores predefinidos
- elfprogramheader1: .int 1, 0x000000, 0x08048000, 0x08048000, 0x96, 0x96, 5, 0x1000
- elfprogramheader2: .int 1, 0x000000, 0x08048000, 0x08048000, 0, 0, 6, 0x1000
- #Nomes dos arquivos de entrada/saída
- arquivoEntrada: .asciz "assembly.s"
- arquivoSaida: .asciz "assembly.o"
- #Mensagens
- abriuArquivo: .asciz "Arquivo foi aberto com sucesso!\n"
- erroIO: .asciz "Erro durante operação de leitura/escrita\n"
- erroArquivo: .asciz "Não foi possível abrir o arquivo:\n"
- gerandoArquivo: .asciz "Gerando estrutura do ELF...\n"
- linkandoArquivo: .asciz "Resolvendo endereços de memória...\n"
- gravandoArquivo: .asciz "Escrevendo arquivo no disco...\n"
- arquivoGerado: .asciz "Arquivo ELF executável gerado!\n"
- msgParametros: .asciz "Uso: as2elf arquivoOrigem arquivoDestino\n"
- .section .bss
- #Armazena o inteiro descritor de arquivo
- .lcomm descritor, 4
- #Espaço para leitura de caracter do arquivo
- .lcomm caracter, 1
- #Buffer que armazena cada linha do arquivo enquanto processa a mesma
- .lcomm buffer, 400
- #Espaço para armazenar parte da esquerda da instrução
- .lcomm instrucao, 10
- #Espaço para escrita dos hexas da seção .data (30.000 bytes alocados)
- .lcomm elfdata, 30000
- #Espaço para escrita dos hexas da seção .text (100.000 bytes alocados)
- .lcomm elftext, 100000
- #Espaço para escrita da tabela de labels (Label / Endereço relativo)
- .lcomm labels, 640
- #Espaço para escrita da lista de nomes usados
- .lcomm labelsUsadosText, 640
- #Espaço para escrita da tabela de labels utilizados (Ponteiro para o label /
- #endereço em que ocorre o label / endereço onde deve ser inserido o valor)
- .lcomm tabelaLabelsText, 640
- #Espaço para escrita da tabela de endereços onde devem ser escritas
- #os endereços absolutos de memória (Endereço no 'elftext' / Endereço absoluto para substituição)
- .lcomm tabelaLabelsData, 640
- #Ponteiro para o fim do elftext
- .lcomm elftextfim, 4
- #Ponteiro para o fim do elfdata
- .lcomm elfdatafim, 4
- #Ponteiro para o fim da tabela labels
- .lcomm labelsfim, 4
- #Ponteiro para o fim da lista labelsUsadosText
- .lcomm labelsUsadosTextFim, 4
- #Comprimento dos hexas da seção .text
- .lcomm tamText, 4
- #Comprimento dos hexas da seção .data
- .lcomm tamData, 4
- #Inteiro que armazena a quantidade de elementos da tabela 'tabelaLabelsData'
- .lcomm countTabelaData, 4
- #Inteiro que armazena a quantidade de elementos da tabela 'tabelaLabelsText'
- .lcomm countTabelaText, 4
- #Temporário para manipulação dos hexas da instrução atual
- .lcomm instrucaohex, 6
- #Qual caso da parte direita da instrução?
- .lcomm caso, 1
- #Qual instrução (posição na lista)?
- .lcomm listaPos, 1
- #Seção que estará sendo processada: 0 - inicial; 1 - .data; 2 - .text
- .lcomm processandoSecao, 1
- #Espaço para armazenar nome dos labels
- #.lcomm label, 100
- label: .ascii "kkkkkkkkkkkkkkkkkkkkkkkkkkk\n"
- #Espaço para armazenar ponteiro para o label
- .lcomm labelPointer, 4
- .section .text
- .globl _start
- /*
- Ação: procurar o label escrito no endereço apontador por 'labelPointer'
- na tabela apontada por %edi, com objetivo de obter seu endereço relativo.
- Parâmetros: %edi: ponteiro para tabela de labels.
- Retorno: %eax: endereço relativo do label buscado.
- */
- buscarLabel:
- labelInicio:
- movl labelPointer, %esi
- movb (%edi), %bl
- cmp (%esi), %bl
- jne labelDiferente
- labelIgual:
- inc %edi
- inc %esi
- movb (%edi), %bl
- cmp $':', %bl
- je labelEncontrado
- cmp (%esi), %bl
- je labelIgual
- labelDiferente:
- inc %edi
- inc %esi
- movb (%edi), %bl
- cmp $':', %bl
- jne labelDiferente
- add $6, %edi
- jmp labelInicio
- labelEncontrado:
- inc %edi
- movl (%edi), %eax
- ret
- /*
- Ação: dado um símbolo e um estado atual, move para o próximo estado
- do autômato definido.
- Parâmetros: %eax: símbolo processado; %ebx: estado atual no autômato.
- Retorno: %eax: estado atual após processamento.
- */
- processaAutomato:
- dec %eax
- cmp $'%', %ebx
- je si1
- cmp $' ', %ebx
- je si2
- cmp $'$', %ebx
- je si3
- cmp $',', %ebx
- je si4
- cmp $'(', %ebx
- je si5
- #A-z
- cmp $97, %ebx
- jge abcmaior
- jmp proxabc
- abcmaior:
- cmp $122, %ebx
- jle si6
- proxabc:
- #0-9
- cmp $48, %ebx
- jge nummaior
- jmp proxnum
- nummaior:
- cmp $57, %ebx
- jle si7
- proxnum:
- jmp si8
- si1:
- movl $s1, %edx
- jmp aSalta
- si2:
- movl $s2, %edx
- jmp aSalta
- si3:
- movl $s3, %edx
- jmp aSalta
- si4:
- movl $s4, %edx
- jmp aSalta
- si5:
- movl $s5, %edx
- jmp aSalta
- si6:
- movl $s6, %edx
- jmp aSalta
- si7:
- movl $s7, %edx
- jmp aSalta
- si8:
- movl $s8, %edx
- jmp aSalta
- aSalta:
- addl %eax, %edx
- xor %eax, %eax
- movb (%edx), %al
- ret
- /*
- Ação: mede o tamanho de um texto a partir de um ponteiro inicial
- até encontrar um caracter '\n'.
- Parâmetros: %eax: ponteiro inicial da mensagem.
- Retorno: %edx: tamanho da mensagem.
- */
- medeMensagem:
- movl $0, %edx
- medeMensagemLoop:
- movb (%eax), %bl
- inc %edx
- inc %eax
- cmp $'\n', %bl
- je medeMensagemFim
- cmp $0, %bl
- je medeMensagemFim
- jmp medeMensagemLoop
- medeMensagemFim:
- dec %eax
- movb $'\n', %bl
- movb %bl, (%eax)
- ret
- /*
- Ação: imprime uma mensagem a partir de um ponteiro inicial até encontrar
- um caracter '\n'.
- Parâmetros: %eax: ponteiro inicial da mensagem.
- Retorno: nenhum.
- */
- imprimirMensagem:
- movl %eax, %ecx #Ponteiro da String
- call medeMensagem #Tamanho da String
- movl $4, %eax
- movl $1, %ebx
- int $0x80
- ret
- /*
- Ação: pula espaços brancos a partir de um ponteiro inicial.
- Parâmetros: %eax: ponteiro inicial.
- Retorno: %eax: ponteiro após pulados os espaços em branco.
- */
- pulaBrancos:
- mov %eax, %edi
- loopPulaBrancos:
- movb (%edi), %al
- inc %edi
- cmp $' ', %al
- je loopPulaBrancos
- cmp $' ', %al
- je loopPulaBrancos
- dec %edi
- mov %edi, %eax
- ret
- /*
- Ação: escreve em 'instrucao' a parte da esquerda (primeira palavra)
- do que estiver em 'buffer'.
- Parâmetros: nenhum.
- Retorno: %eax: ponteiro para o início da parte da direita da instrução.
- */
- primeiraPalavra:
- movl $buffer, %eax
- movl $instrucao, %ebx
- call pulaBrancos
- mov %eax, %edi
- loopPrimeiraPalavra:
- movb (%edi), %al
- movb %al, (%ebx)
- inc %edi
- inc %ebx
- cmp $' ', %al
- je fimPrimeiraPalavra
- cmp $' ', %al
- je fimPrimeiraPalavra
- cmp $'\n', %al
- je fimPrimeiraPalavra
- jmp loopPrimeiraPalavra
- fimPrimeiraPalavra:
- dec %ebx
- movb $' ', (%ebx)
- mov %edi, %eax
- ret
- /*
- Ação: busca a palavra escrita em 'instrucao' em uma determinada lista,
- passada por parâmetro.
- Parâmetros: %esi: ponteiro para a lista em que se deseja buscar.
- Retorno: %eax: posição da palavra na lista.
- */
- verificaPertinencia:
- xor %ecx, %ecx
- recomeca:
- movl $instrucao, %edi
- igual:
- movb (%edi), %al
- movb (%esi), %bl
- inc %edi
- inc %esi
- cmp %al, %bl
- je igual
- dec %edi
- dec %esi
- cmp $'|', %bl
- jne diferente
- cmp $' ', %al
- jne diferente2
- jmp concluido
- diferente:
- inc %esi
- movb (%esi), %bl
- cmp $'|', %bl
- jne diferente
- inc %ecx
- inc %esi
- jmp recomeca
- diferente2:
- inc %ecx
- inc %esi
- jmp recomeca
- concluido:
- mov %ecx, %eax
- ret
- /*
- Ação: através do autômato definido, verifica qual é o caso da parte
- direita da instrução, para ser tratado particularmente.
- Parâmetros: nenhum.
- Retorno: %eax: o caso, após processamento do autômato.
- */
- verificaCaso:
- #Mover endereço da string para o %edi
- mov %eax, %edi
- #Mover estado inicial
- mov $1, %eax
- loopAutomato:
- xor %ebx, %ebx
- movb (%edi), %bl
- inc %edi
- cmp $'\n', %bl
- je finalVerifica
- call processaAutomato
- jmp loopAutomato
- finalVerifica:
- ret
- /*
- Ação: copia parte da instrução (o final da instrução) para um registrador,
- com o objetivo de somar um valor, que corresponde à mudança de
- registrador.
- Parâmetros: %eax: tamanho da instrução.
- Retorno: %eax: a word à qual somar.
- */
- copiaParaSomar:
- mov $instrucaohex, %esi
- add %eax, %esi
- dec %esi #Decrementa porque o tamanho tem um a mais que o índice
- xor %eax, %eax
- movb (%esi), %al
- ret
- /*
- Ação: modifica os hexas de 'instrucaoHex', de acordo com o registrador
- utilizado na instrução.
- Parâmetros: %eax: tamanho da instrução.
- Retorno: %eax: tamanho da instrução.
- */
- trataRegistrador:
- pushl %eax
- call copiaParaSomar
- pushl %edi
- pushl %esi
- pushl %eax
- mov $buffer, %esi
- mov $instrucao, %edi
- mov $2, %ecx
- xor %eax, %eax
- buscaReg:
- movb (%esi), %al
- inc %esi
- cmp $'%', %al
- jne buscaReg
- movb (%esi), %al
- cmp $'e', %al
- jne pulaE
- movb %al, (%edi)
- inc %esi
- inc %edi
- pulaE:
- movb (%esi), %al
- movb %al, (%edi)
- inc %esi
- inc %edi
- loop pulaE
- movb $' ', %al
- movb %al, (%edi)
- mov $registradores, %esi
- call verificaPertinencia
- mov %eax, %ecx
- popl %eax
- popl %esi
- popl %edi
- add %ecx, %eax
- movb %al, (%esi)
- popl %eax
- ret
- /*
- Ação: modifica os hexas de 'instrucaoHex', de acordo com os registradores
- utilizados na instrução.
- Parâmetros: %eax: tamanho da instrução.
- Retorno: %eax: tamanho da instrução.
- */
- trataRegistradores:
- pushl %eax
- call copiaParaSomar
- pushl %edi
- pushl %esi
- pushl %eax
- mov $buffer, %esi
- xor %ebx, %ebx
- xor %edx, %edx
- segundoRegistrador:
- mov $instrucao, %edi
- mov $2, %ecx
- xor %eax, %eax
- buscaReg2:
- movb (%esi), %al
- inc %esi
- cmp $'%', %al
- jne buscaReg2
- movb (%esi), %al
- cmp $'e', %al
- jne pulaE2
- movb %al, (%edi)
- inc %esi
- inc %edi
- pulaE2:
- movb (%esi), %al
- movb %al, (%edi)
- inc %esi
- inc %edi
- loop pulaE2
- movb $' ', %al
- movb %al, (%edi)
- pushl %esi
- pushl %ebx
- mov $registradores, %esi
- call verificaPertinencia
- sal $3, %edx
- add %eax, %edx
- popl %ebx
- popl %esi
- cmp $0, %bl
- mov $1, %ebx
- je segundoRegistrador
- popl %eax
- popl %esi
- popl %edi
- add %edx, %eax
- movb %al, (%esi)
- popl %eax
- ret
- /*
- Ação: quando chamada, encontra-se num ponto em que há um label de
- memória que precisa ser resolvido. É buscado então o valor re-
- lativo daquele label e salvo numa tabela que contém:
- endereço a substituir / valor relativo a substituir.
- Parâmetros: %eax: tamanho da instrução SEM o endereço de memória.
- Retorno: %eax: tamanho da instrução COM o endereço de memória.
- */
- trataMemoria:
- pushl %eax
- mov $buffer, %esi
- mov $label, %edi
- pulaMemoria:
- movb (%esi), %al
- inc %esi
- cmp $'$', %al
- jne pulaMemoria
- copiaMemoria:
- movb (%esi), %al
- inc %esi
- cmp $',', %al
- je fimMemoria
- cmp $' ', %al
- je fimMemoria
- cmp $' ', %al
- je fimMemoria
- movb %al, (%edi)
- inc %edi
- jmp copiaMemoria
- fimMemoria:
- mov $labels, %edi
- #Colocar o endereço de 'label' em 'labelPointer'
- movl $label, %eax
- movl %eax, labelPointer
- call buscarLabel
- movl %eax, %ebx #Salvar valor do label em %ebx
- #Calcular onde guardar na tabela tabelaLabelsData
- movl $8, %eax
- movl countTabelaData, %ecx
- mul %ecx
- movl $tabelaLabelsData, %edi
- add %eax, %edi
- #Salvar endereço da linha no código e endereço (relativo) do dado
- movl elftextfim, %edx
- popl %eax #tamanho da instrução
- add $4, %eax
- add %eax, %edx
- sub $4, %edx #tamanho sem considerar o espaço para o endereço (4 bytes)
- #Cópia dos endereços
- movl %edx, (%edi)
- add $4, %edi
- movl %ebx, (%edi)
- #Incremento do count
- movl countTabelaData, %ecx
- inc %ecx
- movl %ecx, countTabelaData
- ret
- trataLabel:
- pushl %eax #Tamanho sem considerar endereço
- movl $buffer, %eax
- #Chamar as duas rotinas a seguir para posicionar o ponteiro sobre o label
- call primeiraPalavra
- call pulaBrancos
- movl %eax, %esi
- movl labelsUsadosTextFim, %edi
- #construir tabela tabelaLabelText (endereço pra string do label (%edi)
- # (labelsUsadosTextFim) / endereço onde substituir
- # (elftextfim + tamanho da instrução) / endereço que ocorre a utilização do label
- # (elftextfim + tamanho da instrução + 4 - $elftext) )
- #Calcular onde guardar na tabela tabelaLabelsText
- movl $12, %eax
- movl countTabelaText, %ecx
- mul %ecx
- movl $tabelaLabelsText, %edx
- add %eax, %edx
- #Preencher o campo da tabela tabelaLabelsText
- movl %edi, (%edx)
- add $4, %edx
- movl elftextfim, %ebx
- popl %eax
- pushl %eax
- add %eax, %ebx
- movl %ebx, (%edx)
- add $4, %edx
- add $4, %ebx
- movl $elftext, %eax
- sub %eax, %ebx
- movl %ebx, (%edx)
- #Incrementar o count
- inc %ecx
- movl %ecx, countTabelaText
- # popl %esi # %esi foi utilizado temporariamente
- #Copiar label para a lista 'labelsUsadosText'
- loopCopiaLabel:
- movb (%esi), %al
- movb %al, (%edi)
- inc %esi
- inc %edi
- cmp $' ', %al
- je fimCopiaLabel
- cmp $' ', %al
- je fimCopiaLabel
- cmp $'\n', %al
- je fimCopiaLabel
- jmp loopCopiaLabel
- fimCopiaLabel:
- dec %edi
- movb $':', (%edi)
- inc %edi
- movl %edi, labelsUsadosTextFim
- popl %eax
- add $4, %eax
- ret
- /*
- Ação: inverte os bits dos registradores. Utilizado nos casos como
- mov %eax, (%edi) e mov (%edi), %eax, podendo-se utilizar a mesma
- instrução de transformação, apenas invertendo os bits dos registra-
- dores em seguida.
- Parâmetros: %eax: tamanho da instrução
- Retorno: %eax: tamanho da instrução
- */
- inverteBits:
- pushl %eax
- call copiaParaSomar
- movb %al, %bl
- sarb $3, %al
- salb $3, %al
- sub %al, %bl
- sarb $3, %al
- salb $3, %bl
- add %bl, %al
- movb %al, (%esi)
- popl %eax
- ret
- /*
- Ação: Copia o padrão de instrução correspondente para 'instrucaohex'.
- Parâmetros: %eax: caso da instrução; %ebx: posição na lista do conjunto
- de instruções.
- Retorno: %eax: tamanho da instrução
- */
- carregaHex:
- add %ebx, %edi
- xor %ecx, %ecx
- xor %eax, %eax
- movb (%edi), %cl
- mov %ebx, %eax
- mov $6, %ebx #Número de bytes de cada instrução
- mul %ebx
- add %eax, %esi
- mov $instrucaohex, %edi
- pushl %ecx
- xor %ebx, %ebx
- loopCarregaHex:
- movb (%esi), %bl
- inc %esi
- mov %bl, (%edi)
- inc %edi
- loop loopCarregaHex
- popl %eax
- ret
- /*
- Ação: resolve o valor do imediato e o coloca ao final da instrução.
- Parâmetros: %eax: tamanho da instrução SEM o imediato.
- Retorno: %eax: tamanho da instrução COM o imediato (+4 bytes).
- */
- anexaImediato:
- pushl %eax
- mov $buffer, %esi
- xor %eax, %eax
- achaImed:
- inc %esi
- movb (%esi), %al
- cmp $'$', %al
- jne achaImed
- posicionaNum:
- inc %esi
- movb (%esi), %al
- cmp $',', %al
- je numPosicionado
- cmp $' ', %al
- je numPosicionado
- cmp $' ', %al
- je numPosicionado
- jmp posicionaNum
- numPosicionado:
- dec %esi
- call strToInt
- popl %ebx # Tamanho da instrução
- mov $instrucaohex, %edi
- add %ebx, %edi
- movl %eax, (%edi)
- mov %ebx, %eax
- add $4, %eax
- ret
- /*
- Ação: de acordo com o caso da instrução e a posição na lista do
- conjunto de instruções, carrega os opcodes correspondentes
- e chama as rotinas de manipulação dos opcodes para cada caso.
- Ao final, move também o ponteiro que delimita o final do 'elftext'.
- Parâmetros: %eax: caso da instrução; %ebx: posição na lista do conjunto
- de instruções.
- Retorno: nenhum.
- */
- trataCasoInstrucao: #Recebe caso em %eax e posição da lista em %ebx
- xor %eax, %eax
- xor %ebx, %ebx
- movb caso, %al
- movb listaPos, %bl
- #Obs: os casos irão manipular os hexas especificamente e ao final será escrito em 'elftext'
- cmp $1, %eax
- je tc1
- cmp $2, %eax
- je tc2
- cmp $4, %eax
- je tc4
- cmp $5, %eax
- je tc5
- cmp $12, %eax
- je tc12
- cmp $13, %eax
- je tc13
- cmp $15, %eax
- je tc15
- cmp $16, %eax
- je tc16
- cmp $18, %eax
- je tc18
- cmp $21, %eax
- je tc21
- tc1: #Não tem nada
- mov $padraoCaso1, %esi
- mov $tamCaso1, %edi
- call carregaHex
- jmp salvarInstrucao
- tc2: #Tem um registrador
- mov $padraoCaso2, %esi
- mov $tamCaso2, %edi
- call carregaHex
- call trataRegistrador
- jmp salvarInstrucao
- tc4: #Tem um registrador e um registrador apontando pra memória ex: mov %eax, (%edi)
- mov $padraoCaso4, %esi
- mov $tamCaso4, %edi
- call carregaHex
- call trataRegistradores
- jmp salvarInstrucao
- tc5: #Tem dois registradores
- mov $padraoCaso5, %esi
- mov $tamCaso5, %edi
- call carregaHex
- call trataRegistradores
- jmp salvarInstrucao
- tc12: #Tem uma memória imediata e um registrador. Ex: mov $msg, %eax
- mov $padraoCaso12, %esi
- mov $tamCaso12, %edi
- call carregaHex
- call trataRegistrador
- call trataMemoria
- jmp salvarInstrucao
- tc13: #Tem um imediato (restrito ao caso int 0x80)
- mov $padraoCaso13, %esi
- mov $tamCaso13, %edi
- call carregaHex
- jmp salvarInstrucao
- tc15: #Tem um imediato e um registrador
- mov $padraoCaso15, %esi
- mov $tamCaso15, %edi
- call carregaHex
- call trataRegistrador #Tratar separado do imediato e anexar o imediato ao final
- call anexaImediato
- jmp salvarInstrucao
- tc16: #Tem um label
- mov $padraoCaso16, %esi
- mov $tamCaso16, %edi
- call carregaHex
- call trataLabel
- jmp salvarInstrucao
- tc18: #Tem um dado de memória e um registrador. Ex: mov dado, %eax [este caso ainda não foi tratado]
- mov $padraoCaso18, %esi
- mov $tamCaso18, %edi
- call carregaHex
- call trataRegistrador
- call trataMemoria
- jmp salvarInstrucao
- tc21: #Tem um registrador apontando pra memória e um registrador. Ex: mov (%edi), %eax
- mov $padraoCaso21, %esi
- mov $tamCaso21, %edi
- call carregaHex
- call trataRegistradores
- call inverteBits
- salvarInstrucao:
- movl %eax, %ecx #copia tamanho da instrução
- movl elftextfim, %edi
- mov $instrucaohex, %esi
- loopCopia:
- movb (%esi), %al
- movb %al, (%edi)
- inc %esi
- inc %edi
- loop loopCopia
- fimCopia:
- movl %edi, elftextfim
- ret
- /*
- Ação: recebe um ponteiro para o final de uma string que representa
- um número inteiro. Processa da direita para a esquerda, retor-
- nando ao final o valor inteiro correspondente.
- Parâmetros: %esi: ponteiro do final da string.
- Retorno: %eax: valor inteiro convertido.
- */
- strToInt:
- push %esi
- push %edx
- push %ecx
- xor %ebx, %ebx
- mov $1, %ecx
- loopCalculo:
- xor %eax, %eax
- movb (%esi), %al
- cmp $',', %al
- je fimDeConta
- cmp $' ', %al
- je fimDeConta
- cmp $'$', %al
- je fimDeConta
- cmp $' ', %al
- je fimDeConta
- sub $48, %eax
- mul %ecx
- add %eax, %ebx
- mov %ecx, %eax
- mov $10, %ecx
- mul %ecx
- mov %eax, %ecx
- dec %esi
- jmp loopCalculo
- fimDeConta:
- mov %ebx, %eax
- pop %ecx
- pop %edx
- pop %esi
- ret
- /*
- Ação: para cada label de dados trata os dados correspondentes,
- de acordo com a diretiva especificada. Os dados podem ser
- únicos ou múltiplo, eles serão convertidos para o formato
- binário e o ponteiro que delimita o fim do 'elfdata' será
- movido ao final da operação para o final do dado escrito.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- trataCasoDiretiva:
- mov $buffer, %esi
- xor %ebx, %ebx
- xor %ecx, %ecx
- loopCasoDiretiva:
- movb (%esi), %bl
- inc %esi
- cmp $'.', %bl
- jne loopCasoDiretiva
- movb (%esi), %bl
- pulaDiretiva:
- inc %esi
- movb (%esi), %cl
- cmp $' ', %cl
- jne pulaDiretiva
- loopAvancar:
- inc %esi
- movb (%esi), %cl
- cmp $' ', %cl
- je loopAvancar
- movl elfdatafim, %edi # Carregar ponteiro de fim dos dados
- cmp $'a', %bl
- je casoAscii
- cmp $'b', %bl
- je casoByte
- cmp $'i', %bl
- je casoInt
- cmp $'l', %bl
- je casoInt
- cmp $'w', %bl
- je casoWord
- casoAscii:
- inc %esi # Pular as aspas
- dec %edi
- loopAscii:
- movb (%esi), %bl
- inc %esi
- inc %edi
- cmp $92, %bl
- je trataEscape
- cmp $'"', %bl
- je fimTrataCasoDiretiva
- jmp escreveAscii
- trataEscape:
- inc %esi
- movb (%esi), %bl
- cmp $'n', %bl
- je pulaLinha
- cmp $'t', %bl
- je tabulacao
- cmp $'0', %bl
- je fimDeString
- pulaLinha:
- movb $'\n', %bl
- jmp escreveAscii
- tabulacao:
- movb $' ', %bl
- jmp escreveAscii
- fimDeString:
- movb $0, %bl
- jmp escreveAscii
- escreveAscii:
- movb %bl, (%edi)
- #inc %esi
- jmp loopAscii
- casoByte:
- mov $1, %ecx
- jmp loopAvancaNumero
- casoInt:
- mov $4, %ecx
- jmp loopAvancaNumero
- casoWord:
- mov $2, %ecx
- loopAvancaNumero:
- mov (%esi), %bl
- cmp $',', %bl
- je retrocede
- cmp $' ', %bl
- je retrocede
- cmp $'\n', %bl
- je retrocedeUltimo
- inc %esi
- jmp loopAvancaNumero
- retrocedeUltimo:
- xor %edx, %edx
- retrocede:
- dec %esi
- mov (%esi), %bl
- cmp $',', %bl
- je retrocede
- cmp $' ', %bl
- je retrocede
- call strToInt
- cmp $1, %ecx
- jne tentaWord
- call escreveByte
- jmp encerraEscrita
- tentaWord:
- cmp $2, %ecx
- jne tentaInt
- call escreveWord
- jmp encerraEscrita
- tentaInt:
- call escreveInt
- jmp encerraEscrita
- encerraEscrita:
- cmp $0, %edx
- je fimTrataCasoDiretiva
- avanceParaProx:
- inc %esi
- mov (%esi), %bl
- cmp $',', %bl
- je avanceParaProx
- cmp $' ', %bl
- je avanceParaProx
- jmp loopAvancaNumero
- escreveByte:
- movb %bl, (%edi)
- inc %edi
- ret
- escreveInt:
- movl %ebx, (%edi)
- add $4, %edi
- ret
- escreveWord:
- movw %bx, (%edi)
- add $2, %edi
- ret
- fimTrataCasoDiretiva:
- movl %edi, elfdatafim
- ret
- /*
- Ação: de acordo com o conteúdo da linha que está sendo processada, devolve
- um valor:
- 0 - se for uma linha em branco;
- 1 - se conter o label "_start";
- 2 - se conter um label qualquer que não o "_start";
- 3 - se conter uma instrução.
- Parâmetros: nenhum.
- Retorno: %eax: índice para o que tem na linha.
- */
- oQueTemNaLinha:
- mov $buffer, %eax
- mov $1, %ecx
- dec %eax
- loopBusca:
- inc %eax
- movb (%eax), %bl
- cmp $' ', %bl
- je loopBusca
- cmp $' ', %bl
- je loopBusca
- cmp $'_', %bl
- je eStart
- cmp $':', %bl
- je eLabel
- cmp $'\n', %bl
- je talvezBranco
- xor %ecx, %ecx
- jmp loopBusca
- eStart:
- mov $1, %eax
- jmp fimDoQueTemNaLinha
- eLabel:
- mov $2, %eax
- jmp fimDoQueTemNaLinha
- talvezBranco:
- cmp $0, %ecx
- jne eBranco
- mov $3, %eax
- jmp fimDoQueTemNaLinha
- eBranco:
- mov $0, %eax
- fimDoQueTemNaLinha:
- ret
- /*
- Ação: dado que a linha que está sendo processada contém uma instrução,
- essa rotina é chamada para que comece o processamento da
- respectiva instrução, chamando outras rotinas.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- processaInstrucao:
- movl $buffer, %eax
- call imprimirMensagem
- call primeiraPalavra
- call verificaCaso
- mov $caso, %edi
- movb %al, (%edi)
- mov $instrucoes, %esi #Definir que vai efetuar busca na lista de instruções
- call verificaPertinencia
- mov $listaPos, %edi
- movb %al, (%edi)
- call trataCasoInstrucao
- ret
- /*
- Ação: dado que a linha que está sendo processada contém um label,
- essa rotina é chamada para que comece o processamento do
- respectivo label, chamando outras rotinas.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- processaLabel:
- mov $buffer, %eax
- call pulaBrancos
- mov labelsfim, %edx
- loopLabel:
- movb (%eax), %bl
- movb %bl, (%edx)
- inc %eax
- inc %edx
- cmp $':', %bl
- jne loopLabel
- ret
- /*
- Ação: dado que a linha que está sendo processada contém um label
- e está no escopo .text, essa rotina é chamada para que comece
- o processamento do respectivo label, chamando outras rotinas.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- processaLabelText:
- call processaLabel
- movl elftextfim, %eax
- movl $elftext, %ebx
- sub %ebx, %eax
- movl %eax, (%edx)
- add $4, %edx
- movb $'|', %bl
- movb %bl, (%edx)
- inc %edx
- mov %edx, labelsfim
- ret
- /*
- Ação: dado que a linha que está sendo processada contém um label
- e está no escopo .data, essa rotina é chamada para que comece
- o processamento do respectivo label, chamando outras rotinas.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- processaLabelData:
- call processaLabel
- movl elfdatafim, %eax
- movl $elfdata, %ebx
- sub %ebx, %eax
- movl %eax, (%edx)
- add $4, %edx
- movb $'|', %bl
- movb %bl, (%edx)
- inc %edx
- mov %edx, labelsfim
- call trataCasoDiretiva
- ret
- /*
- Ação: dado que a linha que está sendo processada está no escopo .text,
- essa rotina é chamada para que comece o processamento da respecti-
- va linha, chamando outras rotinas.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- processaLinhaText:
- call oQueTemNaLinha
- cmp $3, %eax
- je casoInstruc
- cmp $2, %eax
- je casoLabel
- cmp $1, %eax
- je casoStart
- jmp fimprocessaLinhaText
- casoInstruc:
- call processaInstrucao
- jmp fimprocessaLinhaText
- casoLabel:
- call processaLabelText
- jmp fimprocessaLinhaText
- casoStart:
- movl elftextfim, %eax
- mov $elftext, %ebx
- sub %ebx, %eax
- movl $elfheader, %ecx
- add $24, %ecx
- movl (%ecx), %ebx
- add %eax, %ebx
- movl %ebx, (%ecx)
- fimprocessaLinhaText:
- ret
- /*
- Ação: dado que a linha que está sendo processada está no escopo .data,
- essa rotina é chamada para que comece o processamento da respecti-
- va linha, chamando outras rotinas.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- processaLinhaData:
- call oQueTemNaLinha
- cmp $2, %eax
- jne fimprocessaLinhaData
- call processaLabelData
- fimprocessaLinhaData:
- ret
- /*
- Ação: após uma linha completa montada em 'buffer', verifica escopo
- e inicia o processamento da linha.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- processaLinha:
- movb processandoSecao, %al
- cmp $0, %al
- je inicial
- cmp $1, %al
- je dados
- call processaLinhaText
- jmp fimProcessaLinha
- inicial:
- #procura .data
- mov $buffer, %edx
- inicialLoop:
- movb (%edx), %bl
- inc %edx
- cmp $'\n', %bl
- je fimProcessaLinha
- cmp $'.', %bl
- jne inicialLoop
- movb (%edx), %bl
- cmp $'d', %bl
- jne inicialLoop
- inc %al
- movb %al, processandoSecao
- jmp fimProcessaLinha
- dados:
- #procura .text
- mov $buffer, %edx
- dadosLoop:
- movb (%edx), %bl
- inc %edx
- cmp $'\n', %bl
- je fimDados
- cmp $'.', %bl
- jne dadosLoop
- movb (%edx), %bl
- cmp $'t', %bl
- jne dadosLoop
- movb processandoSecao, %al
- inc %al
- movb %al, processandoSecao
- fimDados:
- cmp $2, %al
- je fimProcessaLinha
- call processaLinhaData
- fimProcessaLinha:
- ret
- /*
- Ação: lê o arquivo linha a linha, jogando cada uma delas
- para o processamento (através da rotina 'processaLinha').
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- lerArquivo:
- movl $buffer, %edi
- loopLerArquivo:
- movl $3, %eax
- movl descritor, %ebx
- movl $caracter, %ecx
- movl $1, %edx
- int $0x80
- test %eax, %eax
- js erro
- movb caracter, %al
- cmp $'@', %al
- je fimLerArquivo
- movb %al, (%edi)
- inc %edi
- cmp $'\n', %al
- jne loopLerArquivo
- call processaLinha
- jmp lerArquivo
- fimLerArquivo:
- # call processaLinha
- ret
- /*
- Ação: baseando-se no ponteiro 'elftextfim', calcula o tamanho do 'elftext',
- armazenando-o em 'tamText'.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- medirText:
- movl elftextfim, %eax
- movl $elftext, %ebx
- sub %ebx, %eax
- movl %eax, tamText
- ret
- /*
- Ação: baseando-se no ponteiro 'elfdatafim', calcula o tamanho do 'elfdata',
- armazenando-o em 'tamData'.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- medirData:
- movl elfdatafim, %eax
- movl $elfdata, %ebx
- sub %ebx, %eax
- movl %eax, tamData
- ret
- /*
- Ação: baseando-se no 'tamText' e no 'tamData', calcula os tamanhos e
- deslocamentos para os programHeaders do programa gerado.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- ajustaProgramHeader:
- movl $elfprogramheader1, %eax
- add $16, %eax
- movl tamText, %ebx
- movl %ebx, (%eax)
- add $4, %eax
- movl %ebx, (%eax)
- movl $elfprogramheader2, %eax
- add $4, %eax
- movl %ebx, (%eax)
- add $0x8048000, %ebx
- add $4, %eax
- movl %ebx, (%eax)
- add $4, %eax
- movl %ebx, (%eax)
- add $4, %eax
- movl tamData, %ebx
- movl %ebx, (%eax)
- add $4, %eax
- movl %ebx, (%eax)
- ret
- /*
- Ação: utilizando-se das informações da tabela 'tabelaLabelsData' e do
- contador 'countTabelaData', substitui cada endereço não resolvido
- pelo endereço relativo somado ao endereço inicial do programa.
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- resolverMemorias:
- movl countTabelaData, %ecx
- cmp $0, %ecx
- je resolvido
- movl $0x08048074, %ebx
- movl tamText, %eax
- add %eax, %ebx
- resolveLoop:
- dec %ecx
- movl %ecx, %eax
- inc %ecx
- movl $8, %edx
- mull %edx
- movl $tabelaLabelsData, %esi
- add %eax, %esi
- movl (%esi), %edi
- add $4, %esi
- movl (%esi), %eax
- add %ebx, %eax
- movl %eax, (%edi)
- loop resolveLoop
- resolvido:
- ret
- /*
- Ação:
- Parâmetros: nenhum.
- Retorno: nenhum.
- */
- resolverSaltos:
- nop
- movl countTabelaText, %ecx
- cmp $0, %ecx
- je labelResolvido
- loopResolveSalto:
- #Calcular onde buscar na tabela tabelaLabelsText
- movl $12, %eax
- dec %ecx
- mul %ecx
- inc %ecx
- movl $tabelaLabelsText, %edx
- add %eax, %edx
- movl (%edx), %esi
- movl %esi, labelPointer
- call buscarLabel
- add $8, %edx
- movl (%edx), %ebx
- sub %ebx, %eax
- sub $4, %edx
- movl (%edx), %edi
- movl %eax, (%edi)
- loop loopResolveSalto
- labelResolvido:
- ret
- /*
- ROTINA PRINCIPAL
- Ação: inicializa ponteiros de final do 'elftext', 'elfdata' e 'labels',
- abre arquivo para leitura, efetua processamento (rotina 'lerArquivo')
- e escreve dados no arquivo destino, na seguinte ordem:
- 1. ElfHeader;
- 2. ProgramHeaders (2);
- 3. ElfText;
- 4. ElfData.
- Parâmetros: ??????
- Retorno: ??????
- */
- _start:
- nop
- #Colocar o endereço de 'elftext' em 'elftextfim'
- movl $elftext, %eax
- movl %eax, elftextfim
- #Colocar o endereço de 'elftext' em 'elftextfim'
- movl $elfdata, %eax
- movl %eax, elfdatafim
- #Colocar o endereço de 'labels' em 'labelsfim'
- movl $labels, %eax
- movl %eax, labelsfim
- #Colocar o endereço de 'labelsUsadosText' em 'labelsUsadosTextFim'
- movl $labelsUsadosText, %eax
- movl %eax, labelsUsadosTextFim
- movl %esp, %ebp
- movl 8(%ebp),%esi
- cmp $0, %esi
- je imprimirHelp
- movb (%esi), %al
- cmp $'-', %al
- je imprimirHelp
- movl %esp, %ebp
- movl $5, %eax
- movl 8(%ebp),%ebx
- movl $00, %ecx
- movl $0444, %edx
- int $0x80
- test %eax, %eax
- js erroEntrada
- sucesso:
- movl %eax, descritor
- movl $abriuArquivo, %eax
- call imprimirMensagem
- movl $gerandoArquivo, %eax
- call imprimirMensagem
- call lerArquivo
- movl $linkandoArquivo, %eax
- call imprimirMensagem
- ss1:
- call medirText
- ss2:
- call medirData
- ss3:
- call ajustaProgramHeader
- ss4:
- call resolverMemorias
- ss5:
- call resolverSaltos
- #Fechar arquivo
- movl descritor, %ebx
- movl $6, %eax
- int $0x80
- #Abrir arquivo para escrita
- movl %esp, %ebp
- movl $5, %eax
- movl 12(%ebp),%ebx
- movl $01102, %ecx
- movl $0755, %edx
- int $0x80
- test %eax, %eax
- movl %eax, descritor
- js erro
- movl $gravandoArquivo, %eax
- call imprimirMensagem
- #Escrever header
- movl $4, %eax
- movl descritor, %ebx
- movl $elfheader, %ecx
- movl $52, %edx
- int $0x80
- test %eax, %eax
- js erro
- #Escrever program header 1
- movl $4, %eax
- movl descritor, %ebx
- movl $elfprogramheader1, %ecx
- movl $32, %edx
- int $0x80
- test %eax, %eax
- js erro
- #Escrever program header 2
- movl $4, %eax
- movl descritor, %ebx
- movl $elfprogramheader2, %ecx
- movl $32, %edx
- int $0x80
- test %eax, %eax
- js erro
- #Calcular tamanho do segmento 'text'
- movl elftextfim, %edx
- movl $elftext, %eax
- sub %eax, %edx
- movl $4, %eax
- movl descritor, %ebx
- movl $elftext, %ecx
- int $0x80
- test %eax, %eax
- js erro
- #Calcular tamanho do segmento 'data'
- movl elfdatafim, %edx
- movl $elfdata, %eax
- sub %eax, %edx
- movl $4, %eax
- movl descritor, %ebx
- movl $elfdata, %ecx
- int $0x80
- test %eax, %eax
- js erro
- movl $arquivoGerado, %eax
- call imprimirMensagem
- jmp fim
- imprimirHelp:
- movl $msgParametros, %eax
- call imprimirMensagem
- jmp fim
- erro:
- movl $erroIO, %eax
- call imprimirMensagem
- jmp fim
- erroEntrada:
- movl $erroArquivo, %eax
- call imprimirMensagem
- movl %esp, %ebp
- movl 8(%ebp),%eax
- call imprimirMensagem
- fim:
- movl $1, %eax
- movl $0, %ebx
- int $0x80
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement