Created
April 10, 2013 00:57
-
-
Save alanyoshida/5350828 to your computer and use it in GitHub Desktop.
OBJETIVO: ler a entrada de um arquivo aberto com letras minúsculas, e convertê-las em maiúsculas, salvando o conteúdo em outro arquivo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#OBJETIVO: ler a entrada de um arquivo aberto com letras minúsculas, | |
#e convertê-las em maiúsculas, salvando o conteúdo em outro arquivo | |
# | |
#PROCESSAMENTO: 1- Abrir o arquivo de entrada | |
#2- Abrir o arquivo de saída | |
#3 - Enquanto não chegamos ao final do arquivo de entrada | |
# a) leia parte do arquivo no buffer | |
# b) passe por cada byte da memória | |
# se o byte for uma letra minúscula, converta-a em maiúscula | |
# c) escreva o buffer no arquivo de saída | |
.section .data | |
####CONSTANTES##### | |
#system call | |
.equ SYS_OPEN, 5 | |
.equ SYS_WRITE, 4 | |
.equ SYS_READ, 3 | |
.equ SYS_CLOSE, 6 | |
.equ SYS_EXIT, 1 | |
#opções para abertura de arquivo | |
#(veja em /usr/include/asm/fcntl.h vários valores. | |
#podemos combiná-los adicionando-os ou encadeando-os). | |
.equ O_RDONLY, 0 | |
.equ O_CREATE_WRONLY_TRUNC, 03101 | |
# Descrotpr padrão de arquivos | |
.equ STDIN, 0 | |
.equ STDOUT, 1 | |
.equ STDERR, 2 | |
# Interrupção syscall | |
.equ LINUX_SYSCALL, 0x80 | |
.equ END_OF_FILE, 0 | |
#Este é o valor de retorno de leitura | |
#que significa que atingimos o final do arquivo | |
.equ NUMBER_ARGUMENTS, 2 | |
.section .bss | |
#Buffer - este é o local onde o dado é carregado | |
#a partir do arquivo de entrada e gravado | |
#dentro do arquivo de saída | |
.equ BUFFER_SIZE, 500 | |
.lcomm BUFFER_DATA, BUFFER_SIZE | |
.section .text | |
#POSIÇÕES DA STACK | |
.equ ST_SIZE_RESERVE, 8 | |
.equ ST_FD_IN, -4 | |
.equ ST_FD_OUT, -8 | |
.equ ST_ARGC, 0 #Número de argumentos | |
.equ ST_ARGV_0, 4 #Nome do programa | |
.equ ST_ARGV_1, 8 #Nome do arquivo de entrada | |
.equ ST_ARGV_2, 12 #Nome do arquivo de saída | |
.globl _start | |
_start: | |
#salva o stack pointer | |
movl %esp,%ebp | |
#aloca espaço para nossos descritores | |
subl $ST_SIZE_RESERVE, %esp | |
open_files: | |
open_fd_in: | |
#####ABRE ARQUIVO DE ENTRADA##### | |
#Open Syscall | |
movl $SYS_OPEN, %eax | |
#Arquivo de entrada em EBX | |
movl ST_ARGV_1(%ebp), %ebx | |
#Read Only Flag | |
movl $O_RDONLY, %ecx | |
#Isso não importância para a leitura | |
movl $0666, %edx | |
#Chama o kernel | |
int $LINUX_SYSCALL | |
store_fd_in: | |
#salva o descritor do arquivo | |
movl %eax, ST_FD_IN(%ebp) | |
open_fd_out: | |
####abre o arquivo de saída#### | |
#abre o arquivo | |
movl $SYS_OPEN, %eax | |
#arquivo de saída em EBX | |
movl ST_ARGV_2(%ebp), %ebx | |
#flags para escrever no arquivo | |
movl $O_CREATE_WRONLY_TRUNC, %ecx | |
#permissão setada para o novo arquivo | |
movl $0666, %edx | |
#chama o kernel | |
int $LINUX_SYSCALL | |
store_fd_out: | |
#guarda o descritor aqui | |
movl %eax, ST_FD_OUT(%ebp) | |
###COMEÇA LOOP### | |
read_loop_begin: | |
###LÊ UM BLOCO DO ARQUIVO DE ENTRADA### | |
movl $SYS_READ, %eax | |
#recupera o descritor do arquivo de entrada | |
movl ST_FD_IN(%ebp), %ebx | |
#local de onde ler dados | |
movl $BUFFER_DATA, %ecx | |
#tamanho do buffer | |
movl $BUFFER_SIZE, %edx | |
#tamanho do buffer lido é retornado em %eax | |
int $LINUX_SYSCALL | |
###SAI AO ALCANÇARMOS O FINAL### | |
#checa o final do marcador do arquivo | |
cmpl $END_OF_FILE, %eax | |
#se encontrar o final ou um erro, vá para o fim | |
jle end_loop | |
continue_read_loop: | |
###CONVERTE O BLOCO PARA MAIÚSCULA### | |
pushl $BUFFER_DATA #localização do buffer | |
pushl %eax #tamanho do buffer | |
call convert_to_upper | |
popl %eax #recupera o tamanho | |
addl $4,%esp #restaura %esp | |
##ESCREVE O BLOCO NO ARQUIVO DE SAÍDA## | |
#tamanho do buffer | |
movl %eax,%edx | |
movl $SYS_WRITE,%eax | |
#arquivo para uso | |
movl ST_FD_OUT(%ebp), %ebx | |
#local do buffer | |
movl $BUFFER_DATA, %ecx | |
int $LINUX_SYSCALL | |
###CONTINUA O LOOP### | |
jmp read_loop_begin | |
end_loop: | |
###FECHA OS ARQUIVOS### | |
# NOTA - não precisamos chegar erros | |
# nesta parte, por condifções de erro | |
# não significam nada de especial aqui | |
movl $SYS_CLOSE, %eax | |
movl ST_FD_OUT(%ebp),%ebx | |
int $LINUX_SYSCALL | |
movl $SYS_CLOSE, %eax | |
movl ST_FD_IN(%ebp), %ebx | |
int $LINUX_SYSCALL | |
###SAÍDA### | |
movl $SYS_EXIT, %eax | |
movl $0, %ebx | |
int $LINUX_SYSCALL | |
#OBJETIVO: Esta função faz a conversão | |
# de maiúsculas por bloco | |
# | |
#INPUT: O primeiro parâmetro é o tamanho | |
# do bloco de memória a converter | |
# | |
# O segundo parâmetro é o endereço | |
# de início do bloco de memória | |
# | |
#OUTPUT: Esta função sobreescreve | |
# o buffer com a versão maiúscula. | |
# | |
#VARIÁVEIS: | |
# %eax - começo do buffer | |
# %ebx - tamanho do buffer | |
# %edi - offset atual do buffer | |
# %cl - byte atual sendo verificado | |
# (primeira parte de %ecx) | |
###CONSTANTES## | |
#Limite mínimo de nossa busca | |
.equ LOWERCASE_A, 'a' | |
#Limite máximo de nossa busca | |
.equ LOWERCASE_Z, 'z' | |
#Conversão entre maiúsculas e minúsculas | |
.equ UPPER_CONVERSION, 'A' - 'a' | |
###CONTEÚDO STACK### | |
.equ ST_BUFFER_LEN, 8 #Tamanho do buffer | |
.equ ST_BUFFER, 12 #buffer atual | |
convert_to_upper: | |
pushl %ebp | |
movl %esp, %ebp | |
###CONFIGURAÇÂO DE VARIÁVEIS### | |
movl ST_BUFFER(%ebp), %eax | |
movl ST_BUFFER_LEN(%ebp), %ebx | |
movl $0, %edi | |
#se um buffer de tamanho zero foi passado | |
#apenas sai | |
cmpl $0, %ebx | |
je end_convert_loop | |
convert_loop: | |
#recupera o byte atual | |
movb (%eax,%edi, 1), %cl | |
#vai para o próximo byte a menos que esteja | |
#entre 'a' e 'z' | |
cmpb $LOWERCASE_A, %cl | |
jl next_byte | |
cmpb $LOWERCASE_Z, %cl | |
jg next_byte | |
#por outro lado converte o byte para maiúsculo | |
addb $UPPER_CONVERSION, %cl | |
#e armazena-o de volta | |
movb %cl, (%eax,%edi,1) | |
next_byte: | |
incl %edi #próximobyte | |
cmpl %edi, %ebx #continua a menos que tenhamos alcançado o final | |
jne convert_loop | |
end_convert_loop: | |
#não retorna valor, apenas sai | |
movl %ebp, %esp | |
popl %ebp | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment