;
;
; -----------------------------------------
;
; Verificador de cpf
; Ricardo, Neimar e Gabriel
; -----------------------------------------
;
;
name "Cpf verificador"
org 100h
novo_cpf:
call PularLinha
mov si, 0
mov bl, 1
mov ah, 09h
mov dx, offset pergunta
int 21h
ler:
mov ah, 01h
int 21h
cmp al, 8
jz escreva_vazio
mov [vetor+si], al
inc si
inc bl
cmp si, 11
jl ler
jmp continua
escreva_vazio:
mov AL, ' '
mov AH, 0Eh
int 10h
cmp bl, 1
jz ler
mov AL, 8
mov AH, 0Eh
int 10h
cmp si, 0
jnz decrementa_si
jmp ler
decrementa_si:
dec bl
dec si
jmp ler
continua:
mov si, 0
call PularLinha
mov ah, 09h
mov dx, offset imprimi_letra
int 21h
imprimir:
mov ah, 02h
mov dl, [vetor+si]
int 21h
inc si
cmp si, 11
jl imprimir
lea bx, vetor
call PularLinha
call VerificaCPF
mov ah,0Ch ; Esvazia o buff
mov al,0
int 21h
cmp valor, 0
jz invalido
cmp valor, 1
jz valido
invalido:
mov ah, 09h
mov dx, offset cpf_invalido
int 21h
jmp pergunta_dnv
valido:
mov ah, 09h
mov dx, offset cpf_valido
int 21h
; Prende o usuario caso ele nao digite s ou n
pergunta_dnv:
call PularLinha
mov ah, 09h
mov dx, offset pergunta_2
int 21h
mov ah, 01h
int 21h
cmp al, 's'
jz novo_cpf
cmp al, 'n'
jz sair
jnz pergunta_dnv
sair:
mov ah, 0 ; Espera uma tecla ser precionada para sair
int 16h
ret;
;declaracao de variaveis
;
;
vetor db 11 dup (?)
cpf_valido db "O cpf e valido. $"
cpf_invalido db "O cpf e invalido. $"
resultado_texto db "Resultado 1 digito: $"
soma_texto db "Soma: $"
valor_texto db "Valor: $"
pergunta_2 db "Voce quer verificar outro cpf? digite 's' ou 'n': $"
pergunta db "Insira um CPF para ser validado: $"
imprimi_letra db "O CPF que foi inserido eh: $"
caracter_vazio db 13, 10, "$"
contador dw ?
soma dw ?
i dw ?
valor dw ?
resultado dw ?
resultado_1 dw ?
resultado_2 dw ?
; Procedimento para Verificar o primeiro digito do CPF
; Este procedimento tem como objetivo verificar os digitos de um CPF, realizar
; a conta necessaria e retornar a variavel valor como 0 se o CPF for invalido
; e a um se for valido
VerificaCPF PROC
; reseta para que possa ser usado novamente
mov ax, 0
mov cx, 0
mov dx, 0
mov soma, 0
mov resultado, 0
mov valor, 0
mov resultado_1, 0
mov resultado_2, 0
mov i, 10 ; Inicializando a variavel contador
mov si, 0 ; Inicializando a variavel soma como 0
loop_soma_1:
mov al, [bx+si] ;
sub al, 30h ; '1' - '0' = 1
mov cl, b.i
mul cl
add soma, ax
inc si
dec i
cmp si, 9
jl loop_soma_1
mov ax, soma
mov cl, 11
div cl
mov b.valor, al
mov al, b.valor
mov cl, 11
mul cl
mov valor, ax
mov ax, soma
sub ax, valor
mov resultado, ax ; RESULTADO
cmp resultado, 0
jz resultado_zero
cmp resultado, 1
jz resultado_um
mov ax, 11
sub ax, resultado
mov resultado, ax
mov resultado_1, ax
jmp continuacao
resultado_zero:
mov resultado_1, 0
jmp continuacao
resultado_um:
mov resultado_1, 0
jmp continuacao
continuacao:
mov ax, 0
mov cx, 0
mov dx, 0
mov soma, 0
mov valor, 0
mov resultado, 0
mov i, 11 ; Inicializando a variavel contador
mov si, 0 ; Inicializando a variavel soma como 1
loop_soma_2:
mov al, [bx+si] ;
sub al, 30h ; '1' - '0' = 1
mov cl, b.i
mul cl
add soma, ax
inc si
dec i
cmp si, 9
jl loop_soma_2
mov al, b.resultado_1
mov cl, 2
mul cl
add soma, ax
mov ax, soma
mov cl, 11
div cl
mov b.valor, al
mov al, b.valor
mov cl, 11
mul cl
mov valor, ax
mov ax, soma
sub ax, valor
mov resultado, ax ; RESULTADO
; Resultado
cmp resultado, 0
jz resultado_zero_2
cmp resultado, 1
jz resultado_um_2
mov ax, 11
sub ax, resultado
mov resultado, ax
mov resultado_2, ax
jmp continuacao_2
resultado_zero_2:
mov resultado_2, 0
jmp continuacao_2
resultado_um_2:
mov resultado_2, 0
jmp continuacao_2
continuacao_2: ; Mensagem de CPF certo ou errado
mov al, vetor[9]
sub al, 30h
cmp b.resultado_1, al
jz primeiro_igual
jnz msg_cpf_invalido
primeiro_igual:
mov al, vetor[10]
sub al, 30h
cmp b.resultado_2, al
jz segundo_igual
jnz msg_cpf_invalido
segundo_igual:
mov valor, 1
jmp fim
msg_cpf_invalido:
mov valor, 0
fim:
ret
VerificaCPF ENDP
; Procedimento para pular uma linha
; Tem como objetivo pular uma linha
PularLinha PROC
mov ah, 09h
mov dx, offset caracter_vazio
int 21h
ret
PularLinha ENDM
; Printar numeros
; Tem como objetivo printar um unico numero,
; caso ele possua mais de um digito ele chama outro
; procedimento chamado print_num_uns
print_num PROC NEAR
PUSH DX
PUSH AX
CMP AX, 0
JNZ not_zero
MOV AL, '0'
MOV AH, 0Eh
INT 10h
JMP printed
not_zero:
; the check SIGN of AX,
; make absolute if it's negative:
CMP AX, 0
JNS positive
NEG AX
MOV AL, '-'
MOV AH, 0Eh
INT 10h
positive:
CALL PRINT_NUM_UNS
printed:
POP AX
POP DX
RET
print_num ENDP
PRINT_NUM_UNS PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
; flag to prevent printing zeros before number:
MOV CX, 1
; (result of "/ 10000" is always less or equal to 9).
MOV BX, 10000 ; 2710h - divider.
; AX is zero?
CMP AX, 0
JZ print_zero
begin_print:
; check divider (if zero go to end_print):
CMP BX,0
JZ end_print
; avoid printing zeros before number:
CMP CX, 0
JE calc
; if AX<BX then result of DIV will be zero:
CMP AX, BX
JB skip
calc:
MOV CX, 0 ; set flag.
MOV DX, 0
DIV BX ; AX = DX:AX / BX (DX=remainder).
; print last digit
; AH is always ZERO, so it's ignored
ADD AL, 30h ; convert to ASCII code.
MOV AH, 0Eh
INT 10h
MOV AX, DX ; get remainder from last div.
skip:
; calculate BX=BX/10
PUSH AX
MOV DX, 0
MOV AX, BX
DIV CS:ten ; AX = DX:AX / 10 (DX=remainder).
MOV BX, AX
POP AX
JMP begin_print
print_zero:
MOV AL, '0'
MOV AH, 0Eh
INT 10h
end_print:
POP DX
POP CX
POP BX
POP AX
RET
PRINT_NUM_UNS ENDP
ten DW 10 ; used as multiplier/divider by SCAN_NUM & print_num.