programa que le um ficheiro com contas e guarda outro ficheiro com contas e resultado


Reads a file with numbers, and saves in another file the result with the sums





;programa que le um ficheiro com contas e guarda outro ficheiro com contas e resultado
STACK SEGMENT PARA STACK ;define o seg pilha
DB 64 DUP ('mystack ')
STACK ENDS

MYDATA SEGMENT PARA 'DATA'
MESG1 DB 'Introduza o nome do ficheiro: ','$'
nomefich DB 12 DUP (' '),0 ; nome do ficheiro lido do teclado
nomefichguarda DB 12 DUP (' '),0 ; nome do ficheiro lido do teclado
;nomefich db '.\teste.txt',0 ;nome do ficheiro, terminado com 0
;nomefichguarda db '.\teste.res',0 ;nome do ficheiro, terminado com 0
;filenam db '.\teste.res',0 ;nome do ficheiro, terminado com 0
NumTemp dw ?

Num1 dw ?
Num2 dw ?
Num3 dw ?
BUF DB 4 DUP (' '),'$' ; buffer para a pilha
line db 0dh,0ah,'$'
PrimNum DB 4 DUP (' '),'$'
SegNum DB 4 DUP (' '),'$'
TercNum DB 4 DUP (' '),'$'
PrimOper DB 4 DUP (' '),'$'
SegOper DB 4 DUP (' '),'$'
TercOper DB 4 DUP (' '),'$'
Result Dw 4 DUP (' '),'$'
Temp DB 1 DUP (' '),'$'
Contador dw 0
Caracter dw 0
fhand dw ? ; handle do ficheiro
PrimNumBin Dw ?
SegNumBin Dw ?
TercNumBin Dw ?
MYDATA ENDS

MYCODE SEGMENT PARA 'CODE' ;define o segmento cod. para o MASM

;------------------------------------------------------------------------
MYPROC PROC FAR ;nome do procedimento MYPROC
ASSUME CS:MYCODE,DS:MYDATA,SS:STACK
PUSH DS ;guarda na pilha o seg. DS
SUB AX,AX ;garante zero no AX
PUSH AX ;guarda zero na pilha
MOV AX,MYDATA ;coloca em AX a posiÁ„o dos DADOS
MOV DS,AX ;coloca essa posiÁ„o no reg. DS
MOV ES,AX ;coloca essa posiÁ„o no reg.ES
;Mostra o cabeÁalho "introduza o nome do ficheiro
LEA DX, MESG1 ; endereÁo da sring com os caracteres lidos
MOV AH,09h ; display de strings, config INT21h
INT 21H ; invoca a interrupÁ„o do 21h do DOS
;fim mostra cabeÁalho

call LerNomeFicheiro


LEA DX, nomefich ;nome do fich a abrir
call abrefich ;abre ficheiro
xor ax,ax

call GuardarLido;guarda nas variaveis
call closefil;como chegou ao fim do ficheiro fecha-o
;guarda nas variaveis correctas os valores
LEA SI, PrimNum
call readn
mov ax,NumTemp
mov PrimNumBin,ax
LEA SI, SegNum
call readn
mov ax,NumTemp
mov SegNumBin,ax
LEA SI, TercNum
call readn
mov ax,NumTemp
mov TercNumBin,ax
;aqui calcula a conta
call contas
;Fim de calcular a conta
;cria o ficheiro .res com os resultados
call CopiaSTR
LEA DX, nomefichguarda ;nome do fich a abrir
call creatfil
LEA DX, nomefichguarda ;nome do fich a abrir
call openfil ;abre ficheiro para escrita
LEA DX, nomefichguarda ;nome do fich a abrir
call guardanoficheiro
mov ax,Result;Result tem 9Ch = 156d
call GuardaResult;guarda no ficheiro o resultado em decimal

call closefil

ret

MYPROC ENDP

;copia uma string para outra
;ENTRADA: nomefich - com o nome do ficheiro inicial
;SAIDA: nomefichguarda - com o nome do ficheiro a guardar

CopiaSTR PROC near

mov bx,0;inicia o contador a zero
;mov cx,conta_caract;inicia bx com o numero total de caracteres
next_char:
mov al,nomefich[bx];move para al o conteudo da posiÁ„o
mov nomefichguarda[bx],al;move para newstring o conteudo do al
cmp al,'.';se encontra o . salta para o fim
je fim
inc bx;incrementa o contador
jmp next_char ;se n„o continua a copiar
fim:
;mov newstring[bx+1],'$';como chegou ao fim, acrescenta o $ de fim de string
mov nomefichguarda[bx+1],'r'
mov nomefichguarda[bx+2],'e'
mov nomefichguarda[bx+3],'s'
ret
CopiaSTR ENDP

;Efectua as contas
;Entrada PrimNumBin;SegNumBin;TercNumBin
;PrimOper;SegOper
;SAIDA Result
contas proc near
cmp PrimOper,'*'
je primeirovezes
cmp PrimOper,'+'
je primeiromais
cmp PrimOper,'-'
;je primeiromenos
call primeiromenos;teve q ser assim se n„o dava erro em salto grande de mais
xor DX,DX
jmp contasFIM
primeirovezes:
cmp SegOper,'*'
je mult_mult
cmp SegOper,'+'
je mult_mais
cmp SegOper,'-'
je mult_menos

mult_mult: ;Result=PrimNumBin*SegNumBin* TercNumBin
mov ax,PrimNumBin
mov cx,SegNumBin
mul cx;ax=ax*cx
mov cx,TercNumBin
mul cx;dx:ax=ax*cx
mov Result,ax
jmp contasFIM
mult_mais: ;Result=PrimNumBin*SegNumBin + TercNumBin
mov ax,PrimNumBin
mov cx,SegNumBin
mul cx;ax=ax*cx
mov cx,TercNumBin
add ax,cx
mov Result,ax
jmp contasFIM
mult_menos: ;Result=PrimNumBin*SegNumBin - TercNumBin
mov ax,PrimNumBin
mov cx,SegNumBin
mul cx;ax=ax*cx
mov cx,TercNumBin
sub ax,cx
mov Result,ax
jmp contasFIM

primeiromais:
cmp SegOper,'*'
je mais_mult
cmp SegOper,'+'
je mais_mais
cmp SegOper,'-'
je mais_menos

mais_mult: ;Result=PrimNumBin+SegNumBin* TercNumBin
mov ax,SegNumBin
mov cx,TercNumBin
mul cx;ax=ax*cx
mov cx,PrimNumBin
add ax,cx
mov Result,ax

jmp contasFIM
mais_mais: ;Result=PrimNumBin+SegNumBin + TercNumBin
mov ax,PrimNumBin
mov bx,SegNumBin
add ax,bx
mov bx,TercNumBin
add ax,bx
mov Result,ax

jmp contasFIM
mais_menos: ;Result=PrimNumBin+SegNumBin - TercNumBin
mov ax,PrimNumBin
mov bx,SegNumBin
add ax,bx
mov bx,TercNumBin
sub ax,bx
mov Result,ax
jmp contasFIM
contasFIM:
ret
contas endp


primeiromenos proc near

cmp SegOper,'*'
je menos_mult
cmp SegOper,'+'
je menos_mais
cmp SegOper,'-'
je menos_menos

menos_mult: ;Result=PrimNumBin-SegNumBin* TercNumBin
mov ax,SegNumBin
mov cx,TercNumBin
mul cx;ax=ax*cx
mov cx,PrimNumBin
sub cx,ax
mov ax,cx
mov Result,ax

ret;jmp contasFIM
menos_mais: ;Result=PrimNumBin-SegNumBin + TercNumBin
mov ax,PrimNumBin
mov bx,SegNumBin
sub ax,bx
mov bx,TercNumBin
add ax,bx
mov Result,ax

ret;jmp contasFIM
menos_menos: ;Result=PrimNumBin-SegNumBin - TercNumBin
mov ax,PrimNumBin
mov bx,SegNumBin
sub ax,bx
mov bx,TercNumBin
sub ax,bx
mov Result,ax
ret;jmp contasFIM
primeiromenos endp

;===PROCEDIMENTO HEX2ASCII
;n„o È usada para nada
HEX2ASCII PROC near
PUSH CX ;salva cx na pilha
PUSH DX ;salva dx na pilha
MOV CL,4 ;abre contagem rotate
MOV CH,4 ;abre contagem digito
DISPH1:
ROL AX,CL ;posicao do numero
PUSH AX ;salva na pilha ax
AND AL,0FH ;recebe digito hexadecimal
ADD AL,30H ;ajusta-o para converter
CMP AL,'9' ;compara com o '9'
JBE DISPH2 ;salta para disph2 se entre nr 0 e 9
ADD AL,7 ;ajusta-o
DISPH2:
MOV AH,6
MOV DL,AL
INT 21H ;manda o digito para o ecra
POP AX ;tira da pilha para o ax para o restaurar
DEC CH
JNZ DISPH1 ;repete
POP DX ;tira da pilha para restaurar dx
POP CX ;tira da pilha para restaurar cx
RET
HEX2ASCII ENDP

guardanoficheiro proc near
LEA DX, PrimNum
call writefil
call indexnum ;posiciona-se no final do fich
LEA DX, PrimOper
call writefil
call indexnum ;posiciona-se no final do fich
LEA DX, SegNum
call writefil
call indexnum ;posiciona-se no final do fich
LEA DX, SegOper
call writefil
call indexnum ;posiciona-se no final do fich
LEA DX, TercNum
call writefil
call indexnum ;posiciona-se no final do fich
LEA DX, TercOper
call writefil
ret
guardanoficheiro endp

;******************************************************************
;Procedimento para converter bin to ascii
;mostra no ecran em ascii o conteudo de AX
;ENTRADA: AX com o valor em binario
;SAIDA: impressao no ecran do numero


GuardaResult proc near
push dx;guarda o dx, cx e bx
push cx
push bx
xor cx,cx;limpa cx
mov bx,10;coloca em bx o valor de 10
dispx11:
xor dx,dx; limpa dx
div bx
push dx; guarda o resto
inc cx; incrementa o contador
or ax,ax; testa quoficiente
jnz dispx11; se n„o for zero
dispx21:
pop dx; mostra o numero
mov ah,6
add dl,30h; converte para ASCII
;int 21h; mostra
mov Temp, dl
push cx
call indexnum ;posiciona-se no final do fich
LEA DX, Temp
mov ah,40h
mov bx,fhand
mov cx,1
;lea dx,Mesg1
int 21h
pop cx
loop dispx21;repete
pop bx;restaura o bx,cx e dx
pop cx
pop dx

ret
GuardaResult endp

;******************************************************************
;Procedimento que converte de ascii para bin
;neste caso separa a string ex: 3401+323=
;colocando em Num1 o 3401 e em Num2 o 323
;ENTRADA: antes ter· que ser feito: LEA DX, polin - para passar o endereÁo da string polin
;SAIDA: Num1; Num2;
readn proc near

push bx ;guarda bx
push cx ;guarda cx
mov cx,10 ;coloca 10 em cx
xor bx,bx ;limpa o resultado
;LEA DX, polin ; endereÁo da sring com os caracteres lidos tambem pode ser assim: ;mov si,offset polin
readn1:
mov al,[si]
;cmp al,0dh ;testa com 0
cmp al,20h ;testa com espaÁo
je primeiron ;salta se menor
cmp al,24h ;testa com $
je primeiron ;salta se menor
sub al,'0' ;converte para BCD
push ax
mov ax,bx ;multiplica por 10
mul cx
mov bx,ax ;guarda o produto
pop ax
xor ah,ah
add bx,ax ;adiciona BCD ao produto
inc si;passa para o caracter seguinte
jmp readn1 ;repete
primeiron:
mov ax,bx ;move o binario para ax
mov NumTemp,ax ;guarda o primeiro numero
inc si;passa para o caracter seguinte
xor ax,ax ;limpa o ax para poder continuar a ler
xor bx,bx;limpa o bx para poder continuar a ler
jmp readn2 ;sai

readn2:
pop cx ;restaura o bx e o cx
pop bx
ret
readn endp

;Guarda nas variaveis correctas os valores lidos
;ENTRADA:
;SAIDA:
GuardarLido proc near
mov contador,1
mov caracter,0
;call abrefich ;abre ficheiro
ler_ini:
mov cx, 1 ;coloca em cx o numero de bytes a ler dados pela variavel tamanho=1
call lefich ;lÍ os dados(1 a 1)
cmp ax, cx ;valida o eof comparando os dados lidos com os dados a ler
jne eof_final_extrai_cor_imagem; se ax n„o for igual ao cx (se os dados a ler n„o forem iguais aos dados lidos) ent„o chegou ao fim
cmp BUF,0dh;se encontra 0a=LF
je ler_ini
cmp BUF,0ah;se encontra 0a=LF
je conta_cor_imagem
mov cx,contador
mov bx,caracter
call GuardaVariavel
inc caracter
jmp ler_ini ;continua a ler ate chegar ao eof
encontraenter:
;inc contador
;mov caracter,0
jmp ler_ini
conta_cor_imagem:
inc contador
mov caracter,0
jmp ler_ini
eof_extrai_cor_imagem: ;como encontrou 4 LF agora È a imagem

xor dx,dx
;call MostraLido;mostra a imagem (pixel a pixel)
inc contador
jmp ler_ini
eof_final_extrai_cor_imagem:
ret
GuardarLido endp


;procedimento que guarda a linha lida nas variaveis
;entrada: BUF, com endereÁo da sring com os caracteres lidos
;entrada BX com o numero da linha lida
GuardaVariavel proc near
mov al,BUF
cmp cx,1
je Linha_11
cmp cx,2
je Linha_21
cmp cx,3
je Linha_31
cmp cx,4
je Linha_41
cmp cx,5
je Linha_51
cmp cx,6
je Linha_61

Linha_11: mov PrimNum[bx],al;move para newstring o conteudo do al
ret
Linha_21: mov PrimOper[bx],al
ret
Linha_31: mov SegNum[bx],al
ret
Linha_41: mov SegOper[bx],al
ret
Linha_51: mov TercNum[bx],al
ret
Linha_61: mov TercOper[bx],al
ret

ret
GuardaVariavel endp

;antes teremos que fazer lea si, polin
; INPUT - SI - endereÁo do inicio da string
; OUTPUT -
; mostra uma string no ecran caracter por caracter
mostra_string proc near
;lea si, polin1
push ax
push dx
again: mov dl, '$'
cmp dl, [SI]
je fim_mostra_string
mov ah, 06
mov dl, [SI]
int 21h
inc si
jmp again
fim_mostra_string: pop dx
pop ax
ret
mostra_string endp

;******************************************************************
;Procedimento para converter bin to ascii
;mostra no ecran em ascii o conteudo de AX
;ENTRADA: AX com o valor em binario
;SAIDA: impressao no ecran do numero
dispx proc near
push dx;guarda o dx, cx e bx
push cx
push bx
xor cx,cx;limpa cx
mov bx,10;coloca em bx o valor de 10
dispx1:
xor dx,dx; limpa dx
div bx
push dx; guarda o resto
inc cx; incrementa o contador
or ax,ax; testa quoficiente
jnz dispx1; se n„o for zero
dispx2:
pop dx; mostra o numero
mov ah,6
add dl,30h; converte para ASCII
int 21h; mostra
loop dispx2;repete
pop bx;restaura o bx,cx e dx
pop cx
pop dx

ret
dispx endp

;*********************************************************************

;procedimento para mostrar o conteudo de uma variavel
;entrada: fazer antes LEA DX, MESG1 ; em que MESG1 È a variavel que queresmo ver
mostraSTR proc near
MOV AH,09h ; display de strings, config INT21h
INT 21H ; invoca a interrupÁ„o do 21h do DOS
ret
mostraSTR endp

;------------------------------------------------
;procedimento que guarda a linha lida nas variaveis
;entrada: BUF, com endereÁo da sring com os caracteres lidos
;entrada BX com o numero da linha lida
mostra proc near
cmp bx,1
je Linha_1
cmp bx,2
je Linha_2
cmp bx,3
je Linha_3
cmp bx,4
je Linha_4
cmp bx,5
je Linha_5
cmp bx,6
je Linha_6

Linha_1: lea dx, PrimNum
ret
Linha_2: lea dx, PrimOper
ret
Linha_3: lea dx, SegNum
ret
Linha_4: lea dx, SegOper
ret
Linha_5: lea dx, TercNum
ret
Linha_6: lea dx, TercOper
ret

ret
mostra endp

;procedimento que lÍ os dados
;Entrada: BUF-buffer para onde vai ler
; fhand-handler do ficheiro que vamos ler
;CX-numero de bytes a ler
;BX-linha a ler (variavel)
;Saida: AX-codigo de erro ou o numero de bytes lidos
lefich proc near
;mov ah,3fh ;ler um ficheiro
;call mostra;vai guardar o lido na variavel correcta
;mov bx, fhand ;coloca em bx o file handler
;int 21h
;ret
mov ah,3fh ;ler um ficheiro
lea dx, BUF ;endereÁo do buffer com os dados lidos
mov bx, fhand ;coloca em bx o file handler
int 21h
ret
lefich endp

;cria o ficheiro de resultados
creatfil proc near
push ax
push cx
push dx
mov ah,3ch
mov cx,00h
;lea dx,filenam
int 21h
mov fhand,ax
pop dx
pop cx
pop ax
ret
creatfil endp
writefil proc near
push bx
push cx
push dx
mov ah,40h
mov bx,fhand
mov cx,4
;lea dx,Mesg1
int 21h
mov ah,40h
mov bx,fhand
mov cx,2
lea dx,line
int 21h
pop dx
pop cx
pop bx
ret
writefil endp
openfil proc near
push ax
push dx
mov al,01h
mov ah,3dh
;lea dx,filenam
int 21h
mov fhand,ax
pop dx
pop ax
ret
openfil endp
;procedimento para abrir um ficheiro
;entrada: nomefich-nome do ficheiro
;antes de chamar fazer LEA DX, nomefich ;nome do fich a abrir
;saida: fhand-handler do ficheiro
abrefich proc near
;push ax
;push dx
MOV AL,00H ;00-so para leitura; 01-so para escrita; 02-para leitura e escrita
MOV AH,3DH ;parametro de abertura, È sempre 3DH
;LEA DX, nomefich ;nome do fich a abrir
INT 21H ;abre
MOV fhand,AX ;guarda o file handle do fich
;pop dx
;pop ax
ret
abrefich endp
;coloca-se no fim do ficheiro
indexnum proc near
mov al,02h
mov ah,42h
mov bx,fhand
mov cx,00h
mov dx,00h
int 21h
ret
indexnum endp

;Procedimento que fecha o ficheiro
;Entrada: fhand- handler do ficheiro a fechar
closefil proc near
push ax
push bx
mov ah,3eh
mov bx,fhand
int 21h
pop bx
pop ax
ret
closefil endp

;Le nome do ficheiro a abrir
LerNomeFicheiro PROC near ; nome do procedimento MYPROC
MOV BX,00 ; carrega em BX o index 0 do buffer BUFF
; leitura e display dos caracteres lidos do teclado
MOV AH,01h ; leitura de um caracter, config INT21h
MOV CX,00h ; coloca o contador a zero
HERE:
INT 21H ; invoca a interrupÁ„o do 21h do DOS
CMP AL,0Dh ; verifca se e' o carriage return
JE NOMORE ; se AL==0Dh salta para a frente
MOV nomefich[BX],AL ; guarda o caracter lido no buffer
CMP AL,0Dh ; verifca se e' o carriage return
JE NOMORE ; se AL==0Dh salta para a frente
CMP CX,79 ; ja' lemos 80 caracteres?
JE NOMORE ; se sim salta para a frente
INC CX ; se n„o, incrementa o contador de caracteres
INC BX ; e incrementa o index do buffer
JMP HERE ; volta para ler mais um caracter
NOMORE:
INC BX
MOV nomefich[BX],'$'
ret
LerNomeFicheiro endp
;---------------------------------------------------
MYCODE ENDS ;fim do codigo
END; FIM de todo o programa

0 comentários:

Enviar um comentário