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