Skip to content

Instantly share code, notes, and snippets.

@alanyoshida
Created April 10, 2013 00:57
Show Gist options
  • Save alanyoshida/5350828 to your computer and use it in GitHub Desktop.
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
#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