Advertisement
Guest User

Assembler Escrito em Assembly

a guest
Apr 25th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .section .data
  2.  
  3.     #Autômato
  4.     s1: # '%'
  5.         .byte   2,  2,  5,  4,  5,  -1, 7,  8,  -1, 10, 12, 12, 13, 15, 15, 16, 18, 18, 19, 21, 21, 22
  6.     s2: # ' '
  7.         .byte 1,    2,  3,  4,  5,  -1, 7,  8,  -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
  8.     s3: # '$'
  9.         .byte 9,    2,  6,  4,  5,  -1, 7,  8,  -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
  10.     s4: # ','
  11.         .byte -1,   3,  3,  4,  5,  -1, 7,  8,  -1, 11, 11, 12, 14, 14, 15, 17, 17, 18, 20, 20, 21, 22
  12.     s5: # '('
  13.         .byte 19,   2,  4,  4,  5,  -1, 7,  8,  -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
  14.     s6: # 'A-z'
  15.         .byte 16,   2,  3,  4,  5,  8,  7,  8,  10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
  16.     s7: # '0-9'
  17.         .byte 22,   2,  3,  4,  5,  7,  7,  8,  13, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
  18.     s8: # 'restante'
  19.         .byte 1,    2,  3,  4,  5,  -1, 7,  8,  -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
  20.  
  21.     #Lista com o conjunto de instruções
  22.     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
  23.     #Lista com o conjunto de registradores
  24.     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|"
  25.  
  26.     #Padrões de hexas para cada instrução e seus respectivos tamanhos
  27.     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
  28.         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
  29.     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
  30.         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
  31.     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
  32.         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
  33.     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
  34.         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
  35.     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
  36.         tamCaso12:  .byte 5, 5, 1, 0, 0
  37.     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
  38.         tamCaso13:  .byte 0, 0, 0, 0, 2
  39.     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
  40.         tamCaso15:  .byte 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 2
  41.     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
  42.         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
  43.     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
  44.         tamCaso18:  .byte 2, 6, 2, 6, 6
  45.     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
  46.         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
  47.  
  48.     #Dados padrões para o cabeçalho do ELF
  49.     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
  50.  
  51.     #Progam headers do ELF com alguns valores predefinidos
  52.     elfprogramheader1: .int   1,    0x000000, 0x08048000, 0x08048000, 0x96, 0x96, 5, 0x1000
  53.     elfprogramheader2: .int   1,    0x000000, 0x08048000, 0x08048000, 0, 0, 6, 0x1000
  54.  
  55.     #Nomes dos arquivos de entrada/saída
  56.     arquivoEntrada:     .asciz "assembly.s"
  57.     arquivoSaida:           .asciz "assembly.o"
  58.  
  59.     #Mensagens
  60.     abriuArquivo:           .asciz "Arquivo foi aberto com sucesso!\n"
  61.     erroIO:                     .asciz "Erro durante operação de leitura/escrita\n"
  62.     erroArquivo:            .asciz "Não foi possível abrir o arquivo:\n"
  63.     gerandoArquivo:     .asciz "Gerando estrutura do ELF...\n"
  64.     linkandoArquivo:    .asciz "Resolvendo endereços de memória...\n"
  65.     gravandoArquivo:    .asciz "Escrevendo arquivo no disco...\n"
  66.     arquivoGerado:      .asciz "Arquivo ELF executável gerado!\n"
  67.     msgParametros:      .asciz "Uso: as2elf arquivoOrigem arquivoDestino\n"
  68.  
  69. .section .bss
  70.  
  71.     #Armazena o inteiro descritor de arquivo
  72.     .lcomm descritor,                       4
  73.     #Espaço para leitura de caracter do arquivo
  74.     .lcomm caracter,                        1
  75.  
  76.     #Buffer que armazena cada linha do arquivo enquanto processa a mesma
  77.     .lcomm buffer,                          400
  78.     #Espaço para armazenar parte da esquerda da instrução
  79.     .lcomm instrucao,                       10
  80.  
  81.     #Espaço para escrita dos hexas da seção .data (30.000 bytes alocados)
  82.     .lcomm elfdata,                         30000
  83.     #Espaço para escrita dos hexas da seção .text (100.000 bytes alocados)
  84.     .lcomm elftext,                         100000
  85.     #Espaço para escrita da tabela de labels (Label / Endereço relativo)
  86.     .lcomm labels,                          640
  87.     #Espaço para escrita da lista de nomes usados
  88.     .lcomm labelsUsadosText,        640
  89.     #Espaço para escrita da tabela de labels utilizados (Ponteiro para o label /
  90.     #endereço em que ocorre o label / endereço onde deve ser inserido o valor)
  91.     .lcomm tabelaLabelsText,        640
  92.     #Espaço para escrita da tabela de endereços onde devem ser escritas
  93.     #os endereços absolutos de memória (Endereço no 'elftext' / Endereço absoluto para substituição)
  94.     .lcomm tabelaLabelsData,        640
  95.  
  96.     #Ponteiro para o fim do elftext
  97.     .lcomm elftextfim,                  4
  98.     #Ponteiro para o fim do elfdata
  99.     .lcomm elfdatafim,                  4
  100.     #Ponteiro para o fim da tabela labels
  101.     .lcomm labelsfim,                       4  
  102.     #Ponteiro para o fim da lista labelsUsadosText
  103.     .lcomm labelsUsadosTextFim, 4
  104.  
  105.     #Comprimento dos hexas da seção .text
  106.     .lcomm tamText,                         4
  107.     #Comprimento dos hexas da seção .data
  108.     .lcomm tamData,                         4
  109.  
  110.     #Inteiro que armazena a quantidade de elementos da tabela 'tabelaLabelsData'
  111.     .lcomm countTabelaData,         4
  112.     #Inteiro que armazena a quantidade de elementos da tabela 'tabelaLabelsText'
  113.     .lcomm countTabelaText,         4
  114.  
  115.     #Temporário para manipulação dos hexas da instrução atual
  116.     .lcomm instrucaohex,                6
  117.  
  118.     #Qual caso da parte direita da instrução?
  119.     .lcomm caso,                                1
  120.     #Qual instrução (posição na lista)?
  121.     .lcomm listaPos,                        1
  122.  
  123.     #Seção que estará sendo processada: 0 - inicial; 1 - .data; 2 - .text
  124.     .lcomm processandoSecao,        1
  125.  
  126.     #Espaço para armazenar nome dos labels
  127.     #.lcomm label,                          100
  128. label: .ascii "kkkkkkkkkkkkkkkkkkkkkkkkkkk\n"
  129.     #Espaço para armazenar ponteiro para o label
  130.     .lcomm labelPointer,                4
  131.  
  132. .section .text
  133. .globl _start
  134.  
  135. /*
  136. Ação:             procurar o label escrito no endereço apontador por 'labelPointer'
  137.                         na tabela apontada por %edi, com objetivo   de obter seu endereço relativo.
  138. Parâmetros: %edi: ponteiro para tabela de labels.
  139. Retorno:        %eax: endereço relativo do label buscado.
  140. */
  141. buscarLabel:
  142.  
  143.     labelInicio:
  144.     movl labelPointer, %esi
  145.     movb (%edi), %bl
  146.     cmp (%esi), %bl
  147.     jne labelDiferente
  148.  
  149.     labelIgual:
  150.     inc %edi
  151.     inc %esi
  152.     movb (%edi), %bl
  153.     cmp $':', %bl
  154.     je labelEncontrado
  155.     cmp (%esi), %bl
  156.     je labelIgual
  157.  
  158.     labelDiferente:
  159.     inc %edi
  160.     inc %esi
  161.     movb (%edi), %bl
  162.     cmp $':', %bl
  163.     jne labelDiferente
  164.     add $6, %edi
  165.     jmp  labelInicio
  166.  
  167.     labelEncontrado:
  168.     inc %edi
  169.     movl (%edi), %eax
  170.  
  171. ret
  172.  
  173.  
  174. /*
  175. Ação:             dado um símbolo e um estado atual, move para o próximo estado
  176.                         do autômato definido.
  177. Parâmetros:    %eax: símbolo processado;  %ebx: estado atual no autômato.
  178. Retorno:        %eax: estado atual após processamento.
  179. */
  180. processaAutomato:
  181.  
  182.     dec %eax
  183.  
  184.     cmp $'%', %ebx
  185.     je si1
  186.     cmp $' ', %ebx
  187.     je si2
  188.     cmp $'$', %ebx
  189.     je si3
  190.     cmp $',', %ebx
  191.     je si4
  192.     cmp $'(', %ebx
  193.     je si5
  194.  
  195.     #A-z
  196.     cmp $97, %ebx
  197.     jge abcmaior
  198.     jmp proxabc
  199.  
  200.     abcmaior:
  201.     cmp $122, %ebx
  202.     jle si6
  203.  
  204.     proxabc:
  205.  
  206.     #0-9
  207.     cmp $48, %ebx
  208.     jge nummaior
  209.     jmp proxnum
  210.  
  211.     nummaior:
  212.     cmp $57, %ebx
  213.     jle si7
  214.  
  215.     proxnum:
  216.     jmp si8
  217.  
  218.     si1:
  219.     movl $s1, %edx
  220.     jmp aSalta
  221.     si2:
  222.     movl $s2, %edx
  223.     jmp aSalta
  224.     si3:
  225.     movl $s3, %edx
  226.     jmp aSalta
  227.     si4:
  228.     movl $s4, %edx
  229.     jmp aSalta
  230.     si5:
  231.     movl $s5, %edx
  232.     jmp aSalta
  233.     si6:
  234.     movl $s6, %edx
  235.     jmp aSalta
  236.     si7:
  237.     movl $s7, %edx
  238.     jmp aSalta
  239.     si8:
  240.     movl $s8, %edx
  241.     jmp aSalta
  242.  
  243.  
  244.     aSalta:
  245.  
  246.     addl %eax, %edx
  247.     xor %eax, %eax
  248.     movb (%edx), %al       
  249.  
  250. ret
  251.  
  252.  
  253. /*
  254. Ação:             mede o tamanho de um texto a partir de um ponteiro inicial
  255.                         até encontrar um caracter '\n'.
  256. Parâmetros:    %eax: ponteiro inicial da mensagem.
  257. Retorno:        %edx: tamanho da mensagem.
  258. */
  259. medeMensagem:
  260.  
  261.     movl $0, %edx
  262.     medeMensagemLoop:
  263.     movb (%eax), %bl
  264.     inc %edx
  265.     inc %eax
  266.     cmp $'\n', %bl
  267.     je medeMensagemFim
  268.     cmp $0, %bl
  269.     je medeMensagemFim
  270.     jmp medeMensagemLoop
  271.  
  272.     medeMensagemFim:
  273.     dec %eax
  274.     movb $'\n', %bl
  275.     movb %bl, (%eax)
  276.  
  277. ret
  278.  
  279.  
  280. /*
  281. Ação:             imprime uma mensagem a partir de um ponteiro inicial até encontrar
  282.                         um caracter '\n'.
  283. Parâmetros:    %eax: ponteiro inicial da mensagem.
  284. Retorno:        nenhum.
  285. */
  286. imprimirMensagem:
  287.  
  288.     movl %eax, %ecx     #Ponteiro da String
  289.     call medeMensagem   #Tamanho da String
  290.     movl $4, %eax
  291.     movl $1, %ebx
  292.     int $0x80
  293.  
  294. ret
  295.  
  296.  
  297. /*
  298. Ação:             pula espaços brancos a partir de um ponteiro inicial.
  299. Parâmetros:    %eax: ponteiro inicial.
  300. Retorno:        %eax: ponteiro após pulados os espaços em branco.
  301. */
  302. pulaBrancos:
  303.  
  304.     mov %eax, %edi
  305.     loopPulaBrancos:
  306.     movb (%edi), %al
  307.     inc %edi
  308.     cmp $' ', %al
  309.     je loopPulaBrancos
  310.     cmp $'  ', %al
  311.     je loopPulaBrancos
  312.     dec %edi
  313.     mov %edi, %eax
  314.  
  315. ret
  316.  
  317.  
  318. /*
  319. Ação:             escreve em 'instrucao' a parte da esquerda (primeira palavra)
  320.                         do que estiver em 'buffer'.
  321. Parâmetros:    nenhum.
  322. Retorno:        %eax: ponteiro para o início da parte da direita da instrução.
  323. */
  324. primeiraPalavra:
  325.  
  326.     movl $buffer, %eax
  327.     movl $instrucao, %ebx
  328.     call pulaBrancos
  329.     mov %eax, %edi
  330.  
  331.     loopPrimeiraPalavra:
  332.     movb (%edi), %al
  333.     movb %al, (%ebx)
  334.     inc %edi
  335.     inc %ebx
  336.     cmp $' ', %al
  337.     je fimPrimeiraPalavra
  338.     cmp $'  ', %al
  339.     je fimPrimeiraPalavra
  340.     cmp $'\n', %al
  341.     je fimPrimeiraPalavra
  342.     jmp loopPrimeiraPalavra
  343.  
  344.     fimPrimeiraPalavra:
  345.  
  346.     dec %ebx
  347.  
  348.     movb $' ', (%ebx)
  349.  
  350.     mov %edi, %eax
  351.  
  352. ret
  353.  
  354.  
  355. /*
  356. Ação:             busca a palavra escrita em 'instrucao' em uma determinada lista,
  357.                         passada por parâmetro.
  358. Parâmetros:    %esi: ponteiro para a lista em que se deseja buscar.
  359. Retorno:        %eax: posição da palavra na lista.
  360. */
  361. verificaPertinencia:
  362.  
  363.     xor %ecx, %ecx
  364.  
  365.     recomeca:
  366.     movl $instrucao, %edi
  367.  
  368.     igual:
  369.     movb (%edi), %al
  370.     movb (%esi), %bl
  371.     inc %edi
  372.     inc %esi
  373.     cmp %al, %bl
  374.     je igual
  375.  
  376.     dec %edi
  377.     dec %esi
  378.    
  379.     cmp $'|', %bl
  380.     jne diferente
  381.  
  382.     cmp $' ', %al
  383.     jne diferente2
  384.  
  385.     jmp concluido
  386.  
  387.     diferente:
  388.     inc %esi
  389.     movb (%esi), %bl
  390.     cmp $'|', %bl
  391.     jne diferente
  392.     inc %ecx
  393.     inc %esi
  394.     jmp recomeca
  395.  
  396.     diferente2:
  397.     inc %ecx
  398.     inc %esi
  399.     jmp recomeca
  400.  
  401.     concluido:
  402.     mov %ecx, %eax
  403.  
  404. ret
  405.  
  406.  
  407. /*
  408. Ação:             através do autômato definido, verifica qual é o caso da parte
  409.                         direita da instrução, para ser tratado particularmente.
  410. Parâmetros:    nenhum.
  411. Retorno:        %eax: o caso, após processamento do autômato.
  412. */
  413. verificaCaso:
  414.  
  415.     #Mover endereço da string para o %edi
  416.     mov %eax, %edi
  417.  
  418.     #Mover estado inicial
  419.     mov $1, %eax
  420.  
  421.     loopAutomato:
  422.     xor %ebx, %ebx
  423.     movb (%edi), %bl
  424.     inc %edi
  425.     cmp $'\n', %bl
  426.     je finalVerifica
  427.     call processaAutomato
  428.     jmp loopAutomato
  429.  
  430.     finalVerifica:
  431.  
  432. ret
  433.  
  434.  
  435. /*
  436. Ação:             copia parte da instrução (o final da instrução) para um registrador,
  437.                         com o objetivo de somar um valor, que corresponde à mudança de
  438.                         registrador.
  439. Parâmetros:    %eax: tamanho da instrução.
  440. Retorno:        %eax: a word à qual somar.
  441. */
  442. copiaParaSomar:
  443.  
  444.     mov $instrucaohex, %esi
  445.     add %eax, %esi
  446.     dec %esi    #Decrementa porque o tamanho tem um a mais que o índice
  447.  
  448.     xor %eax, %eax
  449.     movb (%esi), %al
  450.  
  451. ret
  452.  
  453.  
  454. /*
  455. Ação:             modifica os hexas de 'instrucaoHex', de acordo com o registrador
  456.                         utilizado na instrução.
  457. Parâmetros:    %eax: tamanho da instrução.
  458. Retorno:        %eax: tamanho da instrução.
  459. */
  460. trataRegistrador:
  461.  
  462.     pushl %eax
  463.  
  464.     call copiaParaSomar
  465.  
  466.     pushl %edi
  467.     pushl %esi
  468.     pushl %eax
  469.  
  470.     mov $buffer, %esi
  471.   mov $instrucao, %edi
  472.     mov $2, %ecx
  473.  
  474.     xor %eax, %eax
  475.    
  476.     buscaReg:
  477.     movb (%esi), %al
  478.     inc %esi
  479.     cmp $'%', %al
  480.     jne buscaReg
  481.  
  482.     movb (%esi), %al
  483.     cmp $'e', %al
  484.     jne pulaE
  485.     movb %al, (%edi)
  486.     inc %esi
  487.     inc %edi
  488.  
  489.     pulaE:
  490.     movb (%esi), %al
  491.     movb %al, (%edi)
  492.     inc %esi
  493.     inc %edi
  494.     loop pulaE
  495.  
  496.     movb $' ', %al
  497.     movb %al, (%edi)
  498.  
  499.     mov $registradores, %esi
  500.     call verificaPertinencia
  501.  
  502.     mov %eax, %ecx
  503.  
  504.     popl %eax
  505.     popl %esi
  506.     popl %edi
  507.  
  508.     add %ecx, %eax
  509.     movb %al, (%esi)
  510.  
  511.     popl %eax
  512.  
  513. ret
  514.  
  515.  
  516. /*
  517. Ação:             modifica os hexas de 'instrucaoHex', de acordo com os registradores
  518.                         utilizados na instrução.
  519. Parâmetros:    %eax: tamanho da instrução.
  520. Retorno:        %eax: tamanho da instrução.
  521. */
  522. trataRegistradores:
  523.  
  524.     pushl %eax
  525.  
  526.     call copiaParaSomar
  527.  
  528.     pushl %edi
  529.     pushl %esi
  530.     pushl %eax
  531.  
  532.     mov $buffer, %esi
  533.     xor %ebx, %ebx
  534.     xor %edx, %edx
  535.  
  536.     segundoRegistrador:
  537.   mov $instrucao, %edi
  538.     mov $2, %ecx
  539.  
  540.     xor %eax, %eax
  541.    
  542.     buscaReg2:
  543.     movb (%esi), %al
  544.     inc %esi
  545.     cmp $'%', %al
  546.     jne buscaReg2
  547.  
  548.     movb (%esi), %al
  549.     cmp $'e', %al
  550.     jne pulaE2
  551.     movb %al, (%edi)
  552.     inc %esi
  553.     inc %edi
  554.  
  555.     pulaE2:
  556.     movb (%esi), %al
  557.     movb %al, (%edi)
  558.     inc %esi
  559.     inc %edi
  560.     loop pulaE2
  561.  
  562.     movb $' ', %al
  563.     movb %al, (%edi)
  564.  
  565.     pushl %esi
  566.     pushl %ebx
  567.  
  568.     mov $registradores, %esi
  569.     call verificaPertinencia
  570.  
  571.     sal $3, %edx
  572.  
  573.     add %eax, %edx
  574.  
  575.     popl %ebx
  576.     popl %esi
  577.  
  578.     cmp $0, %bl
  579.     mov $1, %ebx
  580.     je segundoRegistrador
  581.  
  582.     popl %eax
  583.     popl %esi
  584.     popl %edi
  585.  
  586.     add %edx, %eax
  587.  
  588.     movb %al, (%esi)
  589.  
  590.     popl %eax
  591.  
  592. ret
  593.  
  594.  
  595. /*
  596. Ação:             quando chamada, encontra-se num ponto em que há um label de
  597.                         memória que precisa ser resolvido. É buscado então o valor re-
  598.                         lativo daquele label e salvo numa tabela que contém:
  599.                         endereço a substituir / valor relativo a substituir.
  600. Parâmetros:    %eax: tamanho da instrução SEM o endereço de memória.
  601. Retorno:        %eax: tamanho da instrução COM o endereço de memória.
  602. */
  603. trataMemoria:
  604.  
  605.     pushl %eax
  606.  
  607.     mov $buffer, %esi
  608.     mov $label, %edi
  609.  
  610.     pulaMemoria:
  611.     movb (%esi), %al
  612.     inc %esi
  613.     cmp $'$', %al
  614.     jne pulaMemoria
  615.  
  616.     copiaMemoria:
  617.     movb (%esi), %al
  618.     inc %esi
  619.     cmp $',', %al
  620.     je fimMemoria
  621.     cmp $' ', %al
  622.     je fimMemoria
  623.     cmp $'  ', %al
  624.     je fimMemoria
  625.     movb %al, (%edi)
  626.     inc %edi
  627.     jmp copiaMemoria
  628.  
  629.     fimMemoria:
  630.  
  631.     mov $labels, %edi
  632.     #Colocar o endereço de 'label' em 'labelPointer'
  633.     movl $label, %eax
  634.     movl %eax, labelPointer
  635.     call buscarLabel
  636.  
  637.     movl %eax, %ebx #Salvar valor do label em %ebx
  638.  
  639.     #Calcular onde guardar na tabela tabelaLabelsData
  640.     movl $8, %eax
  641.     movl countTabelaData, %ecx
  642.     mul %ecx
  643.     movl $tabelaLabelsData, %edi
  644.     add %eax, %edi
  645.  
  646.     #Salvar endereço da linha no código e endereço (relativo) do dado
  647.     movl elftextfim, %edx  
  648.     popl %eax #tamanho da instrução
  649.     add $4, %eax
  650.     add %eax, %edx
  651.     sub $4, %edx #tamanho sem considerar o espaço para o endereço (4 bytes)
  652.  
  653.     #Cópia dos endereços
  654.     movl %edx, (%edi)
  655.     add $4, %edi
  656.     movl %ebx, (%edi)
  657.  
  658.     #Incremento do count
  659.     movl countTabelaData, %ecx
  660.     inc %ecx
  661.     movl %ecx, countTabelaData
  662.  
  663. ret
  664.  
  665.  
  666. trataLabel:
  667.  
  668.     pushl %eax #Tamanho sem considerar endereço
  669.  
  670.     movl $buffer, %eax
  671.  
  672.     #Chamar as duas rotinas a seguir para posicionar o ponteiro sobre o label
  673.     call primeiraPalavra
  674.     call pulaBrancos
  675.  
  676.     movl %eax, %esi
  677.     movl labelsUsadosTextFim, %edi
  678.  
  679.  
  680.     #construir tabela tabelaLabelText (endereço pra string do label (%edi)
  681.     # (labelsUsadosTextFim) / endereço onde substituir
  682.     # (elftextfim + tamanho da instrução) / endereço que ocorre a utilização do label
  683.     # (elftextfim + tamanho da instrução + 4 - $elftext) )
  684.  
  685.     #Calcular onde guardar na tabela tabelaLabelsText
  686.     movl $12, %eax
  687.     movl countTabelaText, %ecx
  688.     mul %ecx
  689.     movl $tabelaLabelsText, %edx
  690.     add %eax, %edx
  691.  
  692.     #Preencher o campo da tabela tabelaLabelsText
  693.     movl %edi, (%edx)
  694.     add $4, %edx
  695.     movl elftextfim, %ebx
  696.     popl %eax
  697.     pushl %eax
  698.     add %eax, %ebx
  699.     movl %ebx, (%edx)
  700.  
  701.     add $4, %edx
  702.     add $4, %ebx
  703.     movl $elftext, %eax
  704.     sub %eax, %ebx
  705.     movl %ebx, (%edx)
  706.  
  707.     #Incrementar o count
  708.     inc %ecx
  709.     movl %ecx, countTabelaText
  710.  
  711. #   popl %esi #  %esi foi utilizado temporariamente
  712.  
  713.     #Copiar label para a lista 'labelsUsadosText'
  714.     loopCopiaLabel:
  715.     movb (%esi), %al
  716.     movb %al, (%edi)
  717.     inc %esi
  718.     inc %edi
  719.     cmp $' ', %al
  720.     je fimCopiaLabel
  721.     cmp $'  ', %al
  722.     je fimCopiaLabel
  723.     cmp $'\n', %al
  724.     je fimCopiaLabel
  725.     jmp loopCopiaLabel
  726.  
  727.     fimCopiaLabel:
  728.  
  729.     dec %edi
  730.     movb $':', (%edi)
  731.     inc %edi
  732.  
  733.  
  734.     movl %edi, labelsUsadosTextFim
  735.  
  736.     popl %eax
  737.     add $4, %eax
  738.  
  739. ret
  740.  
  741.  
  742. /*
  743. Ação:             inverte os bits dos registradores. Utilizado nos casos como
  744.                         mov %eax, (%edi) e mov (%edi), %eax, podendo-se utilizar a mesma
  745.                         instrução de transformação, apenas invertendo os bits dos registra-
  746.                         dores em seguida.
  747. Parâmetros:    %eax: tamanho da instrução
  748. Retorno:        %eax: tamanho da instrução
  749. */
  750. inverteBits:
  751.  
  752.     pushl %eax
  753.  
  754.     call copiaParaSomar
  755.  
  756.     movb %al, %bl  
  757.  
  758.     sarb $3, %al
  759.     salb $3, %al
  760.     sub %al, %bl
  761.  
  762.     sarb $3, %al
  763.  
  764.     salb $3, %bl
  765.  
  766.     add %bl, %al
  767.  
  768.     movb %al, (%esi)
  769.  
  770.     popl %eax
  771.  
  772. ret
  773.  
  774.  
  775. /*
  776. Ação:             Copia o padrão de instrução correspondente para 'instrucaohex'.
  777. Parâmetros:    %eax: caso da instrução; %ebx: posição na lista do conjunto
  778.                         de instruções.
  779. Retorno:        %eax: tamanho da instrução
  780. */
  781. carregaHex:
  782.  
  783.     add %ebx, %edi
  784.     xor %ecx, %ecx
  785.     xor %eax, %eax
  786.     movb (%edi), %cl
  787.  
  788.     mov %ebx, %eax
  789.     mov $6, %ebx #Número de bytes de cada instrução
  790.     mul %ebx
  791.  
  792.     add %eax, %esi
  793.  
  794.     mov $instrucaohex, %edi
  795.  
  796.     pushl %ecx
  797.  
  798.     xor %ebx, %ebx
  799.     loopCarregaHex:
  800.     movb (%esi), %bl
  801.     inc %esi
  802.     mov %bl, (%edi)
  803.     inc %edi
  804.     loop loopCarregaHex
  805.  
  806.     popl %eax
  807.  
  808. ret
  809.  
  810.  
  811. /*
  812. Ação:             resolve o valor do imediato e o coloca ao final da instrução.
  813. Parâmetros:    %eax: tamanho da instrução SEM o imediato.
  814. Retorno:        %eax: tamanho da instrução COM o imediato (+4 bytes).
  815. */
  816. anexaImediato:
  817.  
  818.     pushl %eax
  819.  
  820.     mov $buffer, %esi
  821.     xor %eax, %eax
  822.  
  823.     achaImed:
  824.     inc %esi
  825.     movb (%esi), %al
  826.     cmp $'$', %al
  827.     jne achaImed
  828.  
  829.     posicionaNum:
  830.     inc %esi
  831.     movb (%esi), %al
  832.     cmp $',', %al
  833.     je numPosicionado
  834.     cmp $' ', %al
  835.     je numPosicionado
  836.     cmp $'  ', %al
  837.     je numPosicionado
  838.     jmp posicionaNum
  839.  
  840.     numPosicionado:
  841.  
  842.     dec %esi
  843.  
  844.     call strToInt
  845.  
  846.     popl %ebx # Tamanho da instrução
  847.  
  848.     mov $instrucaohex, %edi
  849.     add %ebx, %edi
  850.    
  851.     movl %eax, (%edi)
  852.     mov %ebx, %eax
  853.     add $4, %eax
  854.  
  855. ret
  856.  
  857.  
  858. /*
  859. Ação:             de acordo com o caso da instrução e a posição na lista do
  860.                         conjunto de instruções, carrega os opcodes correspondentes
  861.                         e chama as rotinas de manipulação dos opcodes para cada caso.
  862.                         Ao final, move também o ponteiro que delimita o final do 'elftext'.
  863. Parâmetros:    %eax: caso da instrução; %ebx: posição na lista do conjunto
  864.                         de instruções.
  865. Retorno:        nenhum.
  866. */
  867. trataCasoInstrucao: #Recebe caso em %eax e posição da lista em %ebx
  868.  
  869.     xor %eax, %eax
  870.     xor %ebx, %ebx
  871.     movb caso, %al
  872.     movb listaPos, %bl
  873.  
  874.     #Obs: os casos irão manipular os hexas especificamente e ao final será escrito em 'elftext'
  875.     cmp $1, %eax
  876.     je tc1
  877.     cmp $2, %eax
  878.     je tc2
  879.     cmp $4, %eax
  880.     je tc4
  881.     cmp $5, %eax
  882.     je tc5
  883.     cmp $12, %eax
  884.     je tc12
  885.     cmp $13, %eax
  886.     je tc13
  887.     cmp $15, %eax
  888.     je tc15
  889.     cmp $16, %eax
  890.     je tc16
  891.     cmp $18, %eax
  892.     je tc18
  893.     cmp $21, %eax
  894.     je tc21
  895.  
  896.     tc1: #Não tem nada
  897.     mov $padraoCaso1, %esi
  898.     mov $tamCaso1, %edi
  899.     call carregaHex
  900.     jmp salvarInstrucao
  901.  
  902.     tc2: #Tem um registrador
  903.     mov $padraoCaso2, %esi
  904.     mov $tamCaso2, %edi
  905.     call carregaHex
  906.     call trataRegistrador
  907.     jmp salvarInstrucao
  908.  
  909.     tc4: #Tem um registrador e um registrador apontando pra memória ex: mov %eax, (%edi)
  910.     mov $padraoCaso4, %esi
  911.     mov $tamCaso4, %edi
  912.     call carregaHex
  913.     call trataRegistradores
  914.     jmp salvarInstrucao
  915.  
  916.     tc5: #Tem dois registradores
  917.     mov $padraoCaso5, %esi
  918.     mov $tamCaso5, %edi
  919.     call carregaHex
  920.     call trataRegistradores
  921.     jmp salvarInstrucao
  922.  
  923.    
  924.     tc12: #Tem uma memória imediata e um registrador. Ex: mov $msg, %eax
  925.     mov $padraoCaso12, %esi
  926.     mov $tamCaso12, %edi
  927.     call carregaHex
  928.     call trataRegistrador
  929.     call trataMemoria
  930.     jmp salvarInstrucao
  931.  
  932.     tc13: #Tem um imediato (restrito ao caso int 0x80)
  933.     mov $padraoCaso13, %esi
  934.     mov $tamCaso13, %edi
  935.     call carregaHex
  936.     jmp salvarInstrucao
  937.  
  938.     tc15: #Tem um imediato e um registrador
  939.     mov $padraoCaso15, %esi
  940.     mov $tamCaso15, %edi
  941.     call carregaHex
  942.     call trataRegistrador #Tratar separado do imediato e anexar o imediato ao final
  943.     call anexaImediato
  944.     jmp salvarInstrucao
  945.  
  946.     tc16: #Tem um label
  947.     mov $padraoCaso16, %esi
  948.     mov $tamCaso16, %edi
  949.     call carregaHex
  950.     call trataLabel
  951.     jmp salvarInstrucao
  952.  
  953.     tc18: #Tem um dado de memória e um registrador. Ex: mov dado, %eax [este caso ainda não foi tratado]
  954.     mov $padraoCaso18, %esi
  955.     mov $tamCaso18, %edi
  956.     call carregaHex
  957.     call trataRegistrador
  958.     call trataMemoria
  959.     jmp salvarInstrucao
  960.  
  961.  
  962.     tc21: #Tem um registrador apontando pra memória e um registrador. Ex: mov (%edi), %eax
  963.     mov $padraoCaso21, %esi
  964.     mov $tamCaso21, %edi
  965.     call carregaHex
  966.     call trataRegistradores
  967.     call inverteBits
  968.  
  969.     salvarInstrucao:
  970.     movl %eax, %ecx #copia tamanho da instrução
  971.     movl elftextfim, %edi  
  972.     mov $instrucaohex, %esi
  973.  
  974.     loopCopia:
  975.     movb (%esi), %al
  976.     movb %al, (%edi)
  977.     inc %esi
  978.     inc %edi
  979.     loop loopCopia
  980.  
  981.     fimCopia:
  982.     movl %edi, elftextfim
  983.    
  984. ret
  985.  
  986.  
  987. /*
  988. Ação:             recebe um ponteiro para o final de uma string que representa
  989.                         um número inteiro. Processa da direita para a esquerda, retor-
  990.                         nando ao final o valor inteiro correspondente.
  991. Parâmetros:    %esi: ponteiro do final da string.
  992. Retorno:        %eax: valor inteiro convertido.
  993. */
  994. strToInt:
  995.  
  996.     push %esi
  997.     push %edx
  998.     push %ecx
  999.  
  1000.     xor %ebx, %ebx
  1001.     mov $1, %ecx
  1002.  
  1003.     loopCalculo:
  1004.     xor %eax, %eax
  1005.     movb (%esi), %al
  1006.     cmp $',', %al
  1007.     je fimDeConta
  1008.     cmp $' ', %al
  1009.     je fimDeConta
  1010.     cmp $'$', %al
  1011.     je fimDeConta
  1012.     cmp $'  ', %al
  1013.     je fimDeConta
  1014.  
  1015.     sub $48, %eax
  1016.     mul %ecx
  1017.     add %eax, %ebx
  1018.  
  1019.     mov %ecx, %eax
  1020.     mov $10, %ecx
  1021.     mul %ecx
  1022.     mov %eax, %ecx
  1023.  
  1024.     dec %esi
  1025.  
  1026.     jmp loopCalculo
  1027.  
  1028.     fimDeConta:
  1029.  
  1030.     mov %ebx, %eax
  1031.     pop %ecx
  1032.     pop %edx
  1033.     pop %esi
  1034.  
  1035. ret
  1036.  
  1037.  
  1038. /*
  1039. Ação:             para cada label de dados trata os dados correspondentes,
  1040.                         de acordo com a diretiva especificada. Os dados podem ser
  1041.                         únicos ou múltiplo, eles serão convertidos para o formato
  1042.                         binário e o ponteiro que delimita o fim do 'elfdata' será
  1043.                         movido ao final da operação para o final do dado escrito.
  1044. Parâmetros:    nenhum.
  1045. Retorno:        nenhum.
  1046. */
  1047. trataCasoDiretiva:
  1048.  
  1049.     mov $buffer, %esi
  1050.  
  1051.     xor %ebx, %ebx
  1052.     xor %ecx, %ecx
  1053.  
  1054.     loopCasoDiretiva:
  1055.     movb (%esi), %bl
  1056.     inc %esi
  1057.     cmp $'.', %bl
  1058.     jne loopCasoDiretiva
  1059.  
  1060.     movb (%esi), %bl
  1061.  
  1062.     pulaDiretiva:
  1063.     inc %esi
  1064.     movb (%esi), %cl
  1065.     cmp $' ', %cl
  1066.     jne pulaDiretiva
  1067.  
  1068.     loopAvancar:
  1069.     inc %esi
  1070.     movb (%esi), %cl
  1071.     cmp $' ', %cl
  1072.     je loopAvancar
  1073.  
  1074.     movl elfdatafim, %edi # Carregar ponteiro de fim dos dados
  1075.  
  1076.     cmp $'a', %bl
  1077.     je casoAscii
  1078.  
  1079.     cmp $'b', %bl
  1080.     je casoByte
  1081.  
  1082.     cmp $'i', %bl
  1083.     je casoInt
  1084.  
  1085.     cmp $'l', %bl
  1086.     je casoInt
  1087.  
  1088.     cmp $'w', %bl
  1089.     je casoWord
  1090.  
  1091.     casoAscii:
  1092.  
  1093.         inc %esi # Pular as aspas
  1094.  
  1095.         dec %edi
  1096.  
  1097.         loopAscii:
  1098.         movb (%esi), %bl
  1099.         inc %esi
  1100.         inc %edi
  1101.         cmp $92, %bl
  1102.         je trataEscape
  1103.         cmp $'"', %bl
  1104.         je fimTrataCasoDiretiva
  1105.  
  1106.         jmp escreveAscii       
  1107.  
  1108.         trataEscape:
  1109.         inc %esi
  1110.         movb (%esi), %bl
  1111.         cmp $'n', %bl
  1112.         je pulaLinha
  1113.         cmp $'t', %bl
  1114.         je tabulacao
  1115.         cmp $'0', %bl
  1116.         je fimDeString
  1117.  
  1118.         pulaLinha:
  1119.             movb $'\n', %bl
  1120.             jmp escreveAscii
  1121.  
  1122.         tabulacao:
  1123.             movb $' ', %bl
  1124.             jmp escreveAscii
  1125.  
  1126.         fimDeString:
  1127.             movb $0, %bl
  1128.             jmp escreveAscii
  1129.  
  1130.     escreveAscii:
  1131.         movb %bl, (%edi)
  1132.         #inc %esi
  1133.         jmp loopAscii
  1134.  
  1135.     casoByte:
  1136.         mov $1, %ecx
  1137.         jmp loopAvancaNumero
  1138.     casoInt:
  1139.         mov $4, %ecx
  1140.         jmp loopAvancaNumero
  1141.     casoWord:  
  1142.         mov $2, %ecx
  1143.  
  1144.     loopAvancaNumero:
  1145.     mov (%esi), %bl
  1146.     cmp $',', %bl
  1147.     je retrocede
  1148.     cmp $' ', %bl
  1149.     je retrocede
  1150.     cmp $'\n', %bl
  1151.     je retrocedeUltimo
  1152.  
  1153.     inc %esi
  1154.     jmp loopAvancaNumero
  1155.  
  1156.     retrocedeUltimo:
  1157.     xor %edx, %edx
  1158.  
  1159.     retrocede:
  1160.     dec %esi
  1161.     mov (%esi), %bl
  1162.     cmp $',', %bl
  1163.     je retrocede
  1164.     cmp $' ', %bl
  1165.     je retrocede
  1166.    
  1167.     call strToInt
  1168.  
  1169.     cmp $1, %ecx
  1170.     jne tentaWord
  1171.     call escreveByte
  1172.     jmp encerraEscrita
  1173.  
  1174.     tentaWord:
  1175.     cmp $2, %ecx
  1176.     jne tentaInt
  1177.     call escreveWord
  1178.     jmp encerraEscrita
  1179.  
  1180.     tentaInt:
  1181.     call escreveInt
  1182.     jmp encerraEscrita
  1183.    
  1184.  
  1185.     encerraEscrita:
  1186.     cmp $0, %edx
  1187.     je fimTrataCasoDiretiva
  1188.  
  1189.     avanceParaProx:
  1190.     inc %esi
  1191.   mov (%esi), %bl
  1192.     cmp $',', %bl
  1193.     je avanceParaProx
  1194.     cmp $' ', %bl
  1195.     je avanceParaProx
  1196.  
  1197.     jmp loopAvancaNumero
  1198.  
  1199.  
  1200.     escreveByte:
  1201.         movb %bl, (%edi)
  1202.         inc %edi
  1203.     ret
  1204.     escreveInt:
  1205.         movl %ebx, (%edi)
  1206.         add $4, %edi
  1207.     ret
  1208.     escreveWord:
  1209.         movw %bx, (%edi)
  1210.         add $2, %edi
  1211.     ret
  1212.     fimTrataCasoDiretiva:
  1213.         movl %edi, elfdatafim
  1214.  
  1215. ret
  1216.  
  1217.  
  1218. /*
  1219. Ação:             de acordo com o conteúdo da linha que está sendo processada, devolve
  1220.                         um valor:
  1221.                         0 - se for uma linha em branco;
  1222.                         1 - se conter o label "_start";
  1223.                         2 - se conter um label qualquer que não o "_start";
  1224.                         3 - se conter uma instrução.
  1225. Parâmetros:    nenhum.
  1226. Retorno:        %eax: índice para o que tem na linha.
  1227. */
  1228. oQueTemNaLinha:
  1229.  
  1230.     mov $buffer, %eax
  1231.     mov $1, %ecx
  1232.     dec %eax
  1233.  
  1234.     loopBusca:
  1235.         inc %eax
  1236.         movb (%eax), %bl
  1237.    
  1238.         cmp $' ', %bl
  1239.         je loopBusca
  1240.         cmp $'  ', %bl
  1241.         je loopBusca
  1242.         cmp $'_', %bl
  1243.         je eStart
  1244.         cmp $':', %bl
  1245.         je eLabel
  1246.         cmp $'\n', %bl
  1247.         je talvezBranco
  1248.  
  1249.         xor %ecx, %ecx
  1250.         jmp loopBusca
  1251.  
  1252.     eStart:
  1253.         mov $1, %eax
  1254.         jmp fimDoQueTemNaLinha
  1255.  
  1256.     eLabel:
  1257.         mov $2, %eax
  1258.         jmp fimDoQueTemNaLinha
  1259.  
  1260.     talvezBranco:
  1261.         cmp $0, %ecx
  1262.         jne eBranco
  1263.  
  1264.     mov $3, %eax
  1265.     jmp fimDoQueTemNaLinha
  1266.  
  1267.  
  1268.     eBranco:
  1269.         mov $0, %eax
  1270.  
  1271.     fimDoQueTemNaLinha:
  1272.  
  1273. ret
  1274.  
  1275.  
  1276. /*
  1277. Ação:             dado que a linha que está sendo processada contém uma instrução,
  1278.                         essa rotina é chamada para que comece o processamento da
  1279.                         respectiva instrução, chamando outras rotinas.
  1280. Parâmetros:    nenhum.
  1281. Retorno:        nenhum.
  1282. */
  1283. processaInstrucao:
  1284.  
  1285.     movl $buffer, %eax
  1286.   call imprimirMensagem
  1287.  
  1288.     call primeiraPalavra
  1289.     call verificaCaso
  1290.  
  1291.     mov $caso, %edi
  1292.     movb %al, (%edi)
  1293.  
  1294.     mov $instrucoes, %esi #Definir que vai efetuar busca na lista de instruções
  1295.     call verificaPertinencia
  1296.  
  1297.     mov $listaPos, %edi
  1298.     movb %al, (%edi)
  1299.  
  1300.     call trataCasoInstrucao
  1301.  
  1302. ret
  1303.  
  1304.  
  1305. /*
  1306. Ação:             dado que a linha que está sendo processada contém um label,
  1307.                         essa rotina é chamada para que comece o processamento do
  1308.                         respectivo label, chamando outras rotinas.
  1309. Parâmetros:    nenhum.
  1310. Retorno:        nenhum.
  1311. */
  1312. processaLabel:
  1313.  
  1314.     mov $buffer, %eax
  1315.     call pulaBrancos
  1316.  
  1317.     mov labelsfim, %edx
  1318.    
  1319.     loopLabel:
  1320.     movb (%eax), %bl
  1321.     movb %bl, (%edx)
  1322.     inc %eax
  1323.     inc %edx
  1324.     cmp $':', %bl
  1325.     jne loopLabel
  1326.  
  1327. ret
  1328.  
  1329.  
  1330. /*
  1331. Ação:             dado que a linha que está sendo processada contém um label
  1332.                         e está no escopo .text, essa rotina é chamada para que comece
  1333.                         o processamento do respectivo label, chamando outras rotinas.
  1334. Parâmetros:    nenhum.
  1335. Retorno:        nenhum.
  1336. */
  1337. processaLabelText:
  1338.  
  1339.     call processaLabel
  1340.  
  1341.     movl elftextfim, %eax
  1342.     movl $elftext, %ebx
  1343.     sub %ebx, %eax
  1344.     movl %eax, (%edx)
  1345.  
  1346.     add $4, %edx
  1347.     movb $'|', %bl
  1348.     movb %bl, (%edx)
  1349.     inc %edx
  1350.     mov %edx, labelsfim
  1351.  
  1352. ret
  1353.  
  1354.  
  1355. /*
  1356. Ação:             dado que a linha que está sendo processada contém um label
  1357.                         e está no escopo .data, essa rotina é chamada para que comece
  1358.                         o processamento do respectivo label, chamando outras rotinas.
  1359. Parâmetros:    nenhum.
  1360. Retorno:        nenhum.
  1361. */
  1362. processaLabelData:
  1363.  
  1364.     call processaLabel
  1365.  
  1366.     movl elfdatafim, %eax
  1367.     movl $elfdata, %ebx
  1368.     sub %ebx, %eax
  1369.     movl %eax, (%edx)
  1370.  
  1371.     add $4, %edx
  1372.     movb $'|', %bl
  1373.     movb %bl, (%edx)
  1374.     inc %edx
  1375.     mov %edx, labelsfim
  1376.  
  1377.     call trataCasoDiretiva
  1378.  
  1379. ret
  1380.  
  1381.  
  1382. /*
  1383. Ação:             dado que a linha que está sendo processada está no escopo .text,
  1384.                         essa rotina é chamada para que comece o processamento da respecti-
  1385.                         va linha, chamando outras rotinas.
  1386. Parâmetros:    nenhum.
  1387. Retorno:        nenhum.
  1388. */
  1389. processaLinhaText:
  1390.  
  1391.     call oQueTemNaLinha
  1392.  
  1393.     cmp $3, %eax
  1394.     je casoInstruc
  1395.     cmp $2, %eax
  1396.     je casoLabel
  1397.     cmp $1, %eax
  1398.     je casoStart
  1399.     jmp fimprocessaLinhaText
  1400.  
  1401.     casoInstruc:
  1402.         call processaInstrucao
  1403.         jmp fimprocessaLinhaText
  1404.  
  1405.     casoLabel:
  1406.         call processaLabelText
  1407.         jmp fimprocessaLinhaText
  1408.  
  1409.     casoStart:
  1410.         movl elftextfim, %eax
  1411.         mov $elftext, %ebx
  1412.         sub %ebx, %eax
  1413.         movl $elfheader, %ecx
  1414.         add $24, %ecx
  1415.         movl (%ecx), %ebx
  1416.         add %eax, %ebx
  1417.         movl %ebx, (%ecx)
  1418.  
  1419.     fimprocessaLinhaText:
  1420.  
  1421. ret
  1422.  
  1423.  
  1424. /*
  1425. Ação:             dado que a linha que está sendo processada está no escopo .data,
  1426.                         essa rotina é chamada para que comece o processamento da respecti-
  1427.                         va linha, chamando outras rotinas.
  1428. Parâmetros:    nenhum.
  1429. Retorno:        nenhum.
  1430. */
  1431. processaLinhaData:
  1432.  
  1433.     call oQueTemNaLinha
  1434.  
  1435.     cmp $2, %eax
  1436.     jne fimprocessaLinhaData
  1437.  
  1438.     call processaLabelData
  1439.  
  1440.     fimprocessaLinhaData:
  1441.  
  1442. ret
  1443.  
  1444.  
  1445. /*
  1446. Ação:             após uma linha completa montada em 'buffer', verifica escopo
  1447.                         e inicia o processamento da linha.
  1448. Parâmetros:    nenhum.
  1449. Retorno:        nenhum.
  1450. */
  1451. processaLinha:
  1452.  
  1453.     movb processandoSecao, %al
  1454.     cmp $0, %al
  1455.     je inicial
  1456.     cmp $1, %al
  1457.     je dados
  1458.  
  1459.     call processaLinhaText
  1460.     jmp fimProcessaLinha
  1461.  
  1462.     inicial:
  1463.     #procura .data
  1464.  
  1465.     mov $buffer, %edx
  1466.  
  1467.     inicialLoop:
  1468.  
  1469.     movb (%edx), %bl
  1470.     inc %edx
  1471.  
  1472.     cmp $'\n', %bl
  1473.     je fimProcessaLinha
  1474.  
  1475.     cmp $'.', %bl
  1476.     jne inicialLoop
  1477.  
  1478.     movb (%edx), %bl
  1479.     cmp $'d', %bl
  1480.     jne inicialLoop
  1481.  
  1482.     inc %al
  1483.     movb %al, processandoSecao
  1484.     jmp fimProcessaLinha
  1485.  
  1486.     dados:
  1487.     #procura .text
  1488.  
  1489.     mov $buffer, %edx
  1490.  
  1491.     dadosLoop:
  1492.  
  1493.     movb (%edx), %bl
  1494.     inc %edx
  1495.  
  1496.     cmp $'\n', %bl
  1497.     je fimDados
  1498.  
  1499.     cmp $'.', %bl
  1500.     jne dadosLoop
  1501.  
  1502.     movb (%edx), %bl
  1503.     cmp $'t', %bl
  1504.     jne dadosLoop
  1505.  
  1506.     movb processandoSecao, %al
  1507.     inc %al
  1508.     movb %al, processandoSecao
  1509.  
  1510.     fimDados:
  1511.     cmp $2, %al
  1512.     je fimProcessaLinha
  1513.  
  1514.     call processaLinhaData
  1515.  
  1516.     fimProcessaLinha:
  1517.  
  1518. ret
  1519.  
  1520.  
  1521. /*
  1522. Ação:             lê o arquivo linha a linha, jogando cada uma delas
  1523.                         para o processamento (através da rotina 'processaLinha').
  1524. Parâmetros:    nenhum.
  1525. Retorno:        nenhum.
  1526. */
  1527. lerArquivo:
  1528.  
  1529.     movl $buffer, %edi
  1530.  
  1531.     loopLerArquivo:
  1532.     movl $3, %eax
  1533.     movl descritor, %ebx
  1534.     movl $caracter, %ecx
  1535.     movl $1, %edx
  1536.     int $0x80
  1537.     test %eax, %eax
  1538.     js erro
  1539.  
  1540.     movb caracter, %al
  1541.  
  1542.     cmp $'@', %al
  1543.     je fimLerArquivo
  1544.  
  1545.     movb %al, (%edi)
  1546.     inc %edi
  1547.  
  1548.     cmp $'\n', %al
  1549.     jne loopLerArquivo
  1550.  
  1551.     call processaLinha
  1552.     jmp lerArquivo
  1553.  
  1554.     fimLerArquivo:
  1555.  
  1556. #   call processaLinha
  1557.  
  1558. ret
  1559.  
  1560.  
  1561. /*
  1562. Ação:             baseando-se no ponteiro 'elftextfim', calcula o tamanho do 'elftext',
  1563.                         armazenando-o em 'tamText'.
  1564. Parâmetros:    nenhum.
  1565. Retorno:        nenhum.
  1566. */
  1567. medirText:
  1568.  
  1569.     movl elftextfim, %eax
  1570.     movl $elftext, %ebx
  1571.  
  1572.     sub %ebx, %eax
  1573.  
  1574.     movl %eax, tamText
  1575.  
  1576. ret
  1577.  
  1578.  
  1579. /*
  1580. Ação:             baseando-se no ponteiro 'elfdatafim', calcula o tamanho do 'elfdata',
  1581.                         armazenando-o em 'tamData'.
  1582. Parâmetros:    nenhum.
  1583. Retorno:        nenhum.
  1584. */
  1585. medirData:
  1586.  
  1587.     movl elfdatafim, %eax
  1588.     movl $elfdata, %ebx
  1589.  
  1590.     sub %ebx, %eax
  1591.  
  1592.     movl %eax, tamData
  1593.  
  1594. ret
  1595.  
  1596.  
  1597. /*
  1598. Ação:             baseando-se no 'tamText' e no 'tamData', calcula os tamanhos e
  1599.                         deslocamentos para os programHeaders do programa gerado.
  1600. Parâmetros:    nenhum.
  1601. Retorno:        nenhum.
  1602. */
  1603. ajustaProgramHeader:
  1604.  
  1605.     movl $elfprogramheader1, %eax
  1606.     add $16, %eax
  1607.     movl tamText, %ebx
  1608.     movl %ebx, (%eax)
  1609.     add $4, %eax
  1610.     movl %ebx, (%eax)
  1611.  
  1612.     movl $elfprogramheader2, %eax
  1613.     add $4, %eax
  1614.     movl %ebx, (%eax)
  1615.     add $0x8048000, %ebx
  1616.     add $4, %eax
  1617.     movl %ebx, (%eax)
  1618.     add $4, %eax
  1619.     movl %ebx, (%eax)
  1620.     add $4, %eax
  1621.     movl tamData, %ebx
  1622.     movl %ebx, (%eax)
  1623.     add $4, %eax
  1624.     movl %ebx, (%eax)
  1625.        
  1626. ret
  1627.  
  1628.  
  1629. /*
  1630. Ação:             utilizando-se das informações da tabela 'tabelaLabelsData' e do
  1631.                         contador 'countTabelaData', substitui cada endereço não resolvido
  1632.                         pelo endereço relativo somado ao endereço inicial do programa.
  1633. Parâmetros:    nenhum.
  1634. Retorno:        nenhum.
  1635. */
  1636. resolverMemorias:
  1637.  
  1638.     movl countTabelaData, %ecx
  1639.     cmp $0, %ecx
  1640.     je resolvido
  1641.  
  1642.     movl $0x08048074, %ebx
  1643.     movl tamText, %eax
  1644.     add %eax, %ebx
  1645.  
  1646.     resolveLoop:
  1647.  
  1648.     dec %ecx
  1649.     movl %ecx, %eax
  1650.     inc %ecx
  1651.     movl $8, %edx
  1652.  
  1653.     mull %edx
  1654.  
  1655.     movl $tabelaLabelsData, %esi
  1656.     add %eax, %esi
  1657.  
  1658.     movl (%esi), %edi
  1659.     add $4, %esi
  1660.     movl (%esi), %eax
  1661.  
  1662.     add %ebx, %eax
  1663.  
  1664.     movl %eax, (%edi)
  1665.  
  1666.     loop resolveLoop
  1667.  
  1668.     resolvido:
  1669.  
  1670. ret
  1671.  
  1672.  
  1673. /*
  1674. Ação:            
  1675. Parâmetros:    nenhum.
  1676. Retorno:        nenhum.
  1677. */
  1678. resolverSaltos:
  1679. nop
  1680.     movl countTabelaText, %ecx
  1681.     cmp $0, %ecx
  1682.     je labelResolvido
  1683.  
  1684.  
  1685.  
  1686.     loopResolveSalto:
  1687.     #Calcular onde buscar na tabela tabelaLabelsText
  1688.     movl $12, %eax
  1689.     dec %ecx
  1690.     mul %ecx
  1691.     inc %ecx
  1692.     movl $tabelaLabelsText, %edx
  1693.     add %eax, %edx
  1694.     movl (%edx), %esi
  1695.     movl %esi, labelPointer
  1696.     call buscarLabel
  1697.  
  1698.     add $8, %edx
  1699.     movl (%edx), %ebx
  1700.  
  1701.     sub %ebx, %eax
  1702.  
  1703.     sub $4, %edx
  1704.     movl (%edx), %edi
  1705.     movl %eax, (%edi)  
  1706.  
  1707.  
  1708.     loop loopResolveSalto
  1709.  
  1710.     labelResolvido:
  1711.  
  1712. ret
  1713.  
  1714.  
  1715. /*
  1716. ROTINA PRINCIPAL
  1717. Ação:             inicializa ponteiros de final do 'elftext', 'elfdata' e 'labels',
  1718.                         abre arquivo para leitura, efetua processamento (rotina 'lerArquivo')
  1719.                         e escreve dados no arquivo destino, na seguinte ordem:
  1720.                         1. ElfHeader;
  1721.                         2. ProgramHeaders (2);
  1722.                         3. ElfText;
  1723.                         4. ElfData.
  1724. Parâmetros:    ??????
  1725. Retorno:        ??????
  1726. */
  1727. _start:
  1728.  
  1729.     nop
  1730.  
  1731.     #Colocar o endereço de 'elftext' em 'elftextfim'
  1732.     movl $elftext, %eax
  1733.     movl %eax, elftextfim
  1734.  
  1735.     #Colocar o endereço de 'elftext' em 'elftextfim'
  1736.     movl $elfdata, %eax
  1737.     movl %eax, elfdatafim
  1738.  
  1739.     #Colocar o endereço de 'labels' em 'labelsfim'
  1740.     movl $labels, %eax
  1741.     movl %eax, labelsfim
  1742.  
  1743.     #Colocar o endereço de 'labelsUsadosText' em 'labelsUsadosTextFim'
  1744.     movl $labelsUsadosText, %eax
  1745.     movl %eax, labelsUsadosTextFim
  1746.  
  1747.  
  1748.     movl %esp, %ebp
  1749.     movl 8(%ebp),%esi
  1750.     cmp $0, %esi
  1751.     je imprimirHelp
  1752.     movb (%esi), %al
  1753.     cmp $'-', %al
  1754.     je imprimirHelp
  1755.  
  1756.     movl %esp, %ebp
  1757.     movl $5, %eax
  1758.     movl 8(%ebp),%ebx
  1759.     movl $00, %ecx
  1760.     movl $0444, %edx
  1761.     int $0x80
  1762.     test %eax, %eax
  1763.     js erroEntrada
  1764.  
  1765.     sucesso:
  1766.     movl %eax, descritor
  1767.     movl $abriuArquivo, %eax
  1768.     call imprimirMensagem
  1769.  
  1770.     movl $gerandoArquivo, %eax
  1771.     call imprimirMensagem
  1772.     call lerArquivo
  1773.  
  1774.     movl $linkandoArquivo, %eax
  1775.     call imprimirMensagem
  1776. ss1:
  1777.     call medirText
  1778. ss2:
  1779.     call medirData
  1780. ss3:
  1781.     call ajustaProgramHeader
  1782. ss4:
  1783.     call resolverMemorias
  1784. ss5:
  1785.     call resolverSaltos
  1786.  
  1787.     #Fechar arquivo
  1788.     movl descritor, %ebx
  1789.     movl $6, %eax
  1790.     int $0x80
  1791.  
  1792.     #Abrir arquivo para escrita
  1793.     movl %esp, %ebp
  1794.     movl $5, %eax
  1795.     movl 12(%ebp),%ebx
  1796.     movl $01102, %ecx
  1797.     movl $0755, %edx
  1798.     int $0x80
  1799.     test %eax, %eax
  1800.     movl %eax, descritor
  1801.     js erro
  1802.  
  1803.     movl $gravandoArquivo, %eax
  1804.     call imprimirMensagem
  1805.  
  1806.     #Escrever header
  1807.     movl $4, %eax
  1808.     movl descritor, %ebx
  1809.     movl $elfheader, %ecx
  1810.     movl $52, %edx
  1811.     int $0x80
  1812.     test %eax, %eax
  1813.     js erro
  1814.  
  1815.     #Escrever program header 1
  1816.     movl $4, %eax
  1817.     movl descritor, %ebx
  1818.     movl $elfprogramheader1, %ecx
  1819.     movl $32, %edx
  1820.     int $0x80
  1821.     test %eax, %eax
  1822.     js erro
  1823.  
  1824.     #Escrever program header 2
  1825.     movl $4, %eax
  1826.     movl descritor, %ebx
  1827.     movl $elfprogramheader2, %ecx
  1828.     movl $32, %edx
  1829.     int $0x80
  1830.     test %eax, %eax
  1831.     js erro
  1832.  
  1833.     #Calcular tamanho do segmento 'text'
  1834.     movl elftextfim, %edx
  1835.     movl $elftext, %eax
  1836.     sub %eax, %edx
  1837.  
  1838.     movl $4, %eax
  1839.     movl descritor, %ebx
  1840.     movl $elftext, %ecx
  1841.  
  1842.     int $0x80
  1843.     test %eax, %eax
  1844.     js erro
  1845.  
  1846.     #Calcular tamanho do segmento 'data'
  1847.     movl elfdatafim, %edx
  1848.     movl $elfdata, %eax
  1849.     sub %eax, %edx
  1850.  
  1851.     movl $4, %eax
  1852.     movl descritor, %ebx
  1853.     movl $elfdata, %ecx
  1854.  
  1855.     int $0x80
  1856.     test %eax, %eax
  1857.     js erro
  1858.  
  1859.     movl $arquivoGerado, %eax
  1860.     call imprimirMensagem
  1861.        
  1862.     jmp fim
  1863.  
  1864.     imprimirHelp:
  1865.     movl $msgParametros, %eax
  1866.     call imprimirMensagem
  1867.  
  1868.     jmp fim
  1869.  
  1870.     erro:
  1871.     movl $erroIO, %eax
  1872.     call imprimirMensagem
  1873.     jmp fim
  1874.  
  1875.     erroEntrada:
  1876.     movl $erroArquivo, %eax
  1877.     call imprimirMensagem
  1878.     movl %esp, %ebp
  1879.     movl 8(%ebp),%eax
  1880.     call imprimirMensagem
  1881.  
  1882.  
  1883.     fim:
  1884.     movl $1, %eax
  1885.     movl $0, %ebx
  1886.  
  1887.     int $0x80
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement