Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
INSTITUTO FEDERAL DO ESPÍRITO SANTO – CAMPUS SERRA BACHARELADO EM SISTEMA DE INFORMAÇÃO JEAN CARLOS PENAS RELATÓRIO DO ALGORITMO DE VALIDAÇÃO DE CPF ASSEMBLY & C/C++ SERRA 2013 JEAN CARLOS PENAS RELATÓRIO DO ALGORITMO DE VALIDAÇÃO DE CPF ASSEMBLY & C/C++ Tr ab a l ho ap r esen t ad o à d i s c i p l i n a O rgan iz ação e A r q u i t e t u ra d e Co mp ut ad o r es d o cu rs o Bacha r e l ad o em S i s t em a d e In f o r mação d o In s t i t u t o Fed er a l do E sp í r i t o S an to – C amp us S e r r a , p a r a av a l i a ção p a r c i a l . P ro f e s so r : F l av i o Gi r a l d e l i APRESENTAÇÃO Este trabalho foi elaborado como parte da aplicação das teorias estudadas na disciplina Organização e Arquitetura de computadores, com a finalidade de se obter um melhor um entendimento de alguns conceitos estudados em sala de aula. Foi desenvolvido um algoritmo em assembly e o mesmo em c, o objetivo é analisar alguns aspectos entre as duas linguagens. RELATÓRIO DO ALGORITMO DE VALIDAÇÃO DE CPF ASSEMBLY & C/C++ Em análise de algoritmos, os níveis das linguagens são definidos tomando como referência a aproximação delas com o ser humano, para tal, são classificadas como linguagens de baixo, médio e alto nível. À medida que o nível de abstração de uma linguagem de programação aumenta, as instruções vão ficando mais complexas e em termo de legibilidade se tornam mais eficientes, um exemplo disso seria as linguagens de alto nível (visual basic, pascal, csharp e etc.), em contra partida as linguagens de baixo nível apresentam instruções mais simples, como conseqüência, isso torna o processamento mais rápido, mas a legibilidade se torna ineficiente, pois a quantidade de linhas de código aumenta consideravelmente, um exemplo de linguagem de baixo nível é o Assembly. Foi desenvolvido um algoritmo de validação de CPF em duas linguagens, uma de baixo e a outra de médio nível, trata-se do Assembly e do C, respectivamente. A analogia será feita em três processos:entrada, processamento e saída.Na entrada, espera- se que o usuário digite o CPF para ser validado, em assembly isso acontece da seguinte forma, mas antes precisamos salvar o estado normal dos registradores na pilha, cada vez que chamamos o procedimento e restaurá-los, cada vez que terminam, seja com a instruções PUSH, POP ou PUSHA,POPA, nestes últimos, o armazena-se e restaura-se, respectivamente todos os registradores.O programa informa o momento que o CPF deverá ser digitado, imprimindo a mensagem “DIGITE O CPF $”, para que essa mensagem seja imprimida, cria-se uma variável inicializada com esta mensagem e com um terminador de string “$”, o endereço dessa variável é carregada em DX com a instrução LEA e em seguida é chamado o procedimento IMPRIME, neste procedimento a subfunção “9”, criada para impressão de strings com terminador “$” , é movida para dentro de AH, a parte mais significativa do registrador AX e então a instrução INT 21H executa a subfunção “9”, imprimindo o conteúdo que está em DX, que é a mensagem “DIGITE O CPF”,na linguagem C, este processo está oculto no comando printf(“%s”,enderecodavariavel) ele imprime uma cadeia de caracteres até encontrar um terminador de string que neste caso é o ‘\0’.Em seguida tem a macro SALATALINHA que mov os caracteres ODH e 10 para dentro AL, parte menos significativa do registrador geral AX, e a subfunção de impressão de caracteres OEH é movida para AH e depois a subfunção é executada com a instrução INT 10H, saltando uma linha na tela do usuário, em C, isto é feito com um simples comando printf(“\n”), agora o usuário precisa digitar o CPF para ser validado, mas para que isso aconteça, foi criado uma variável chamada BUFFER, o endereço dela foi movido para dentro do registrador de deslocamento DI e foi movido para DX uma variável constante, inicializada com o endereço da variável BUFFER e depois o procedimento GET_STRING é chamado, o objetivo deste procedimento é capturar o CPF digitado pelo usuário, então o procedimento é executado, ele inicializa o registrador contador CX com zero, se o valor que está DX for menor ou igual 1, ou seja se não tiver nada é gerado um salto que para o rotulo que vai fazer retirada do endereço do GET_STRING da pilha de execução, retornando para o programa principal, caso a condição não seja satisfeita, ele decrementa DX e logo após encontra o rótulo WAIT_FOR_KEY, nele o usuário vai digitando os caracteres enquanto a tela enter não teclada.O processo neste rótulo funciona da seguinte forma,é movido uma subfunção “0” que quando a instrução INT 16H é executada, é esperado que o usuário digite algum caracter e após isto o caracter é movido para o registrador AL, em seguida é verificado se o usuário apertou a tecla enter para sair, senão tiver apertado, ele vai perguntar se o usuário apertou a tecla bakspace, cujo valor na tabela ASCII é 8, caso não tenha digitado outro caracter, este será adicionado para dentro de BUFFER, neste processo, ele pergunta se o registrador CX é maior ou igual ao tamanho(SIZE) da variável buffer que está em DX, então ele volta para o rotulo WAIT_FOR_KEY, para que o usuário continue digitando algo, senão ele insere o caracter na variável BUFFER cujo endereço está em DI, em seguida, ele incrementa DI que é a posição do próximo caracter, incrementa CX que indica o tamanho do tamanho Buffer que está aumentando conforme o usuário vai digitando, e imprime o caracter que foi inserido na variável “BUFFER”, a impressão do caracter acontece, quando é movido a instrução 0EH para dentro do registrador AH e então ela é executada com a instrução INT 10H e depois ele salta novamente para o rótulo “WAIT_FOR_KEY”, mas se o usuário apertou a tecla Bakspace, ele decrementa CX(tamanho do buffer), decrementa DI, que é a posição do caracter dentro da variável, ou seja, ele volta para posição anterior que será sobrescrita na próxima vez que o usuário digitar algo que seja diferente de baskpace(8) e de Enter(ODH) e no final ele salta para WAIT_FOR_KEY, repetindo o mesmo ciclo até que seja digitado a tecla enter, quando esta é acionada ele vai para o rótulo EXIT, mas antes disso DI estará a uma posição a frente, isto é proposital, pois neste rótulo esta posição vai receber o nulo(0) e em seguida o procedimento sai da pilha de execução.O processo de entrada foi satisfeita, o usuário já digitou o CPF, agora começa a validação do CPF, antes de executar o procedimento “PROCESSA”, o registrador DX é inicializado com zero, indicando que, inicialmente, o CPF é falso, move-se o endereço do CPF capturado que está em DI para o registrador SI, move-se o valor 10 para o calculo do primeiro digito para BX e então chama-se o procedimento “PROCESSA”, as variáveis usadas nele são “SOMA”, “SINAL”, “CONT”, “PRI” e “DIGITO1”, a primeira é inicializada com zero, pois vai receber a soma dos produtos, a segunda é inicializada com zero, indicando que o fluxo de validação está no calculo do primeiro dígito, a terceira está inicializada com zero, indicando a posição inicial de um caracter do CPF, ela será usada como condição de parada no nono dígito , a quarta variável está inicializada com zero, pois inicialmente ainda não calculamos o primeiro digito do CPF, depois de inicializadas, encontramos o rótulo “PROXIMO”, nele é movido para dentro de AL,o conteúdo apontado pelo registrador SI e então verifica-se se os nove primeiros dígitos do CPF já foram percorridos, caso não tenha chegado no nono dígito do CPF, ele salta para o rótulo “PULA”, que subtrai o conteúdo que está AL por ‘0’ que na tabela ASCII tem valor 48,então AL passa a ter um numero inteiro que será multiplicado pelo valor que está em BX que é 10 e que a cada salto será decrementado até o nono digito, o resultado do produto que vai está em AX é acumulado na variável SOMA, depois AX é zerado BX é decrementada, a variável CONT é incrementada, quando o nono digito é atingido o fluxo do processamento salta para rótulo “TERMINA”, os registradores são salvos antes de serem usados, em seguida é movido o valor que do DIGITO1 que é zero porque o primeiro digito ainda não foi calculado, e então ele é movido para dentro de AX, o valor 2 é movido para BX é executado a instrução MUL que multiplica o conteúdo que está em BX por AX e escreve o resultado em AX, quando este rótulo é atingido já temos a soma dos produtos dos dígitos então a variável SOMA é somada ao conteúdo que está em AX e o resultado é sobrescrito em AX, o endereço deste é movido para dentro de BX o valor 11, depois o conteúdo que está em AX será dividido(DIV) e multiplicado(MUL) pelo valor que está BX, que é 11, o resultado estará em AX, o endereço deste será movido para dentro da variável VALOR , e o endereço de SOMA será movido para dentro de BX, depois subtrai-se (instrução SUB) o valor que está em BX que é a soma dos produtos pelo valor que está em VALOR que é o resultado da divisão e multiplicação por BX, o resultado estará em BX, este é então movido para a variável RESULTADO, os registradores AX e BX são restaurados com a instrução POP, depois verifica-se se o resultado que está em RESULTADO é 0 , se sim, move-se o valor zero para dentro de DIGITO1 e salta para o rótulo RECALCULA; senão, o fluxo do processamento salta para o rótulo SETA, este compara se o resultado que está na variável RESULTADO é 1, se sim ele salta para o rótulo SETA2, que move para dentro do DIGITO1, o valor zero e salta para recalcula, senão ele salta para o rótulo ETAPA1, que vai mover para dentro de AX, o valor 11, vai subtrair o conteúdo que no RESULTADO pelo conteúdo em AX e sobrescreve AX com o resultado, este é movido para dentro de DIGITO1, e então salta-se para o rótulo RECALCULA.Lembrando que em todos os rótulos e procedimentos os registradores são salvos antes de serem manuseados e recuperados após o uso.No RECALCULA, move-se o endereço do conteúdo que está em DI para SI novamente, para retornar ao endereço inicial apontado pelo registrador SI, adiante é movido para dentro AX, o valor DIGITO1, depois é movido para o registrador SI, o endereço da variável PRI,cujo conteúdo, inicialmente, é 9, esta é a posição do décimo dígito do CPF, pois o primeiro digito esta na posição zero, então o décimo digito do CPF é extraído para dentro de BL , subtrai-se o conteúdo que está em BL por ‘0’ para transformá-lo em um numero inteiro e depois ele é comparado com o digito calculado que está em AX, na parte menos significativa AL, se forem iguais ele salta para o rótulo IGUAL que restaura o conteúdo dos registradores usados no rótulo RECALCULA, o rótulo IGUAL verifica se o segundo digito não foi calculado através da variável SINAL que neste caso representa uma flag que estará setada para 1, quando o segundo digito estiver sido calculado e para zero se for o contrário.Bem, se o segundo digito não foi calculado então o fluxo do processamento salta para rótulo RECALCULA2 que move o endereço do registrador DI para SI, com o intuito de retornar ao endereço inicial da variável BUFFER apontada pelo registrador acessada pelo registrador SI, adiante é movido o valor 11 pára BX com a finalidade se calcular o segundo dígito verificador, depois a variável SOMA é novamente inicializada com zero, a variável SINAL é setada para 1, pois o segundo dígito será calculado,a variável CONT é inicializada com zero, a variável PRI que agora representa o décimo digito do CPF, onde os dígitos são contados a partir da posição zero e em seguida ele salta para o rótulo PROXIMO, fazendo o mesmo percurso, mas desta vez para o calculo do segundo dígito verificador, voltando para o rótulo RECALCULA, se o SINAL for diferente de zero, que significa que o segundo digito já foi calculado, então ele salta o rótulo SALTA e restaura os registradores usados pelo RECALCULA e salta para o rótulo SAI que restaura os registradores usados inicialmente pelo PROCESSA e em seguida o procedimento sai da pilha de execução.Quando o procedimento PROCESSA o resultado é esperado em DX, que estará setado para um se CPF for válido, zero se o CPF for inválido.Em seguida é executada a macro SALTALINHA que já foi mencionada, depois a macro GETCHAR que vai esperar que o usuário digite uma tecla e em seguida o procedimento CLEAR_SCREEN é executado limpando a tela do usuário, todos os registrados são restaurados e logo adiante é feito um salto para o rótulo PROXIMO10 que dará a oportunidade do usuário validar outros CPF’s. Na linguagem C, temos duas funções Digito(CPF,V,digito) e o Evalido(CPF), a função Digito retorna o primeiro digito verificador, quando o valor v está inicializado com o valor 10 para a soma dos produtos dos dígitos, ele retorna o segundo digito verificador quando v é igual 11.Na função Evalido, v é inicializado com o valor 10, calcula-se o primeiro digito e logo adiante calcula-se o segundo dígito pois v foi incrementado ficando com o conteúdo igual a 11, até aqui temos o primeiro e o segundo digito calculado, depois extraímos o nono e o décimo digito do CPF digitado pelo usuário e comparamos os dois dígitos calculados com os do CPF, esta função retornará um caso o CPF for valido e zero se for o contrário. O algoritmo de validação de CPF em C foi escrito com apenas 70 linhas de código, isto por que o algoritmo estava modularizado, ele ainda pode ser mais compactado, agora em assembly, o mesmo problema foi resolvido, mas por um algoritmo escrito com cerca de 360 linhas de código, além disso, o algoritmo em assembly demorou 4 dias para ser construído ao passo que na linguagem c, o mesmo algoritmo foi escrito em duas horas.Por isso é preferível trabalhar com linguagens com alto nível de abstração, pois facilita o entendimento e a correção, mas por outro lado existe uma desvantagem, o programa se torna mais lento e em uma linguagem de baixo nível a execução do programa é mais rápida, pois o processador consegue trabalhar melhor com instruções mais simples. NOME: Jean Carlos Penas INSTITUTO FEDERAL DO ESPÍRITO SANTO – CAMPUS SERRA BACHARELADO EM SISTEMA DE INFORMAÇÃO JEAN CARLOS PENAS RELATÓRIO DO ALGORITMO DE SERRA JEAN CARLOS PENAS RELATÓRIO DO ALGORITMO DE APRESENTAÇÃO RELATÓRIO DO ALGORITMO DE