Hi guys i need a little help fast i have a calculator and its giving me some problems
This calculator reads from a text file the result shows in the terminal but its giving me some troubles
For one only the + operator works
I cant use the overflow function correctly it just gives me the overflow message in an infinite loop those are my two main problems and i dont know what to do can anyone help pls
MAX_BUFFER equ 2048 ; Constante que sera' usada como tamanho maximo de cada bloco lido do ficheiro (2kb)
FICH_ABERTURA equ 00q ; Constante que sera' usada como tipo de abertura pretendido: O_WRONLY + O_CREAT
;-----------------------------------------------------------------------------
section .data
fich_nome db "ACfinal.txt", 0 ; Nome do ficheiro a abrir (em formato ASCIIZ)
fich_handle dd 0 ; Variavel que vai guardar o numero (handle) do ficheiro
fich_bytes dd 0 ; Variavel que vai guardar a quantidade de bytes lidos
str_resultado db "Resultado: "
TAM_RESULTADO equ $ - str_resultado
str_eol db 0xA
TAM_EOL equ $ - str_eol
str_overflow db "Overflow detectado!"
tam_overflow equ $ - str_overflow
num1 dd 0,0,0,0,0,0,0,0 ; int num1[8];
num2 dd 0,0,0,0,0,0,0,0
c_linha dd 0
Doubles dd 0
sinalfinal dd 0
resultado dd 0
temp dd 0
tam_linha dd 0
MAX_LINHA equ 64+2
;-----------------------------------------------------------------------------
section .bss
buffer resb MAX_BUFFER
final resb MAX_LINHA
;-----------------------------------------------------------------------------
section .text
global _start
_start:
; BLOCO 1
; Abre o ficheiro e guarda o handle em [fich_handle]
mov eax, 5 ; Funcao do sistema (system call); 5 = sys_open
mov ebx, fich_nome ; Para sys_open, ebx = endereco do nome do ficheiro (em formato ASCIIZ)
mov ecx, FICH_ABERTURA ; Para sys_open, ecx = tipo de abertura pretendido
int 0x80 ; Chamar o Linux
mov [fich_handle], eax ; Guarda o handle do ficheiro que foi aberto
; BLOCO 2
; Le^ um bloco do ficheiro cujo handle esta em [fich_handle] para buffer
mov eax, 3 ; Funcao do sistema (system call); 4 = sys_read
mov ebx, [fich_handle] ; Para sys_read, ebx = handle de leitura
mov ecx, buffer ; Para sys_read, ecx = endereco do buffer para a leitura
mov edx, MAX_BUFFER ; Para sys_read, edx = tamanho maximo do buffer
int 0x80 ; Chamar o Linux
mov [fich_bytes], eax ; Guarda o tamanho do que foi efectivamente lido
; BLOCO 3
; Procura o \n e calcula o numero de doublewords necessarios
mov esi, buffer
mov ecx, [fich_bytes]
cld
procura_enter:
lodsb
cmp al, 0xA
je fim_palavra
loop procura_enter
fim_palavra:
mov edx, esi ; EDX = endereco do primeiro \n
sub edx, buffer ; EDX = tamanho da primeira palavra mais o enter
dec edx
mov [tam_linha],edx ; numero de bits por linha
add edx,7
shr edx,3 ; numero de dwords na linha
mov [Doubles],edx
; BLOCO 4
; converte uma linha para num1
mov esi,buffer
mov ecx,[Doubles]
mov dword[c_linha],0
numero_um:
push ecx
call conv
mov edx,[c_linha]
shr edx,1
mov [num1+edx],eax
add dword[c_linha],8
pop ecx
loop numero_um
; BLOCO 5
; percorre o buffer inteiro
ciclo_maior:
inc dword[c_linha]
mov esi,buffer
mov ecx,[Doubles]
mov dword[resultado],0
numero_dois:
push ecx
call conv
mov ebx,[resultado]
mov [num2+ebx],eax
add dword[c_linha],8
pop ecx
add dword[resultado],4
loop numero_dois
inc dword[c_linha]
mov ebx,[c_linha]
mov dl, [buffer+ebx]
cmp dl, '+'
jne nao_salta
jmp soma
nao_salta:
cmp dl, '-'
jne nao_salta2
jmp subtrai
nao_salta2:
cmp dl, '*'
jne nao_salta3
jmp troca_ou_nao
nao_salta3:
cmp dl, '/'
jne escreve_256
jmp troca_ou_nao
escreve_256:
; exibe str_resultado
mov edx, TAM_RESULTADO
mov ecx, str_resultado
mov ebx, 1
mov eax, 4
int 0x80
mov ecx,[Doubles]
mov dword[resultado],0
ciclo_escreve:
push ecx
mov ebx,[resultado]
mov eax,[num1+ebx]
call escreve32
pop ecx
add dword[resultado],4
loop ciclo_escreve
; exibe str_eol (quebra de linha)
mov edx, TAM_EOL
mov ecx, str_eol
mov ebx, 1
mov eax, 4
int 0x80
; BLOCO N
; Termina o programa
mov eax, 1
mov ebx, 0
int 0x80
;------------------------------------------------------------
;
;BLOCO ESCRITA
escreve_final:
escreve32:
mov [temp], eax ; transforma "temp" em string
mov ecx, 8 ; 4 bytes em [temp] => 8 digitos hexadecimais
mov edi, final
mov ebx, [temp]
cld
xor eax, eax
escreve_conv:
rol ebx, 4
mov eax, ebx
and eax, 0xF
cmp eax, 0x9
jbe escreve_digito
add al, 'A'-0xA
jmp escreve_prox
escreve_digito:
add al, '0'
escreve_prox:
stosb
loop escreve_conv
escreve_resultado:
; exibe o resultado
mov edx, 8
mov ecx, final
mov ebx, 1
mov eax, 4
int 0x80
ret
;------------------------------------------------------------------------------------------
conv:
; converte o numero em "buffer" de string em hexadecimal
; para numero inteiro
xor eax, eax
xor ebx, ebx
mov esi, buffer
add esi, [c_linha]
cld
mov ecx, 8
jecxz pede_num_fim
pede_num_conv:
lodsb
cmp al, '9'
jbe pede_num_digito
add al, 9
pede_num_digito:
and al, 0xF
shl ebx, 4
add ebx, eax
loop pede_num_conv
pede_num_fim:
; copia o resultado para eax e retorna
mov eax, ebx
ret
;-----------------------------------------------------------------------------------------
soma: ; chega aqui com eax=num1 e ebx=num2; deve sair com eax=resultado
mov ecx, 0
mov edx, 0
clc
ciclo_somar:
mov eax, [num1+edx]
mov ebx, [num2+edx]
adc eax, ebx
mov [num1+ecx*4],eax
inc ecx
mov edx,ecx
shl edx,2
cmp ecx,[Doubles]
jb ciclo_somar
jmp ciclo_maior
subtrai: ; chega aqui com eax=num1 e ebx=num2; deve sair com eax=resultado
mov esi, num1
mov edi, num2
mov ecx, [Doubles]
clc
ciclo_subtrair:
mov eax, [esi]
sbb eax, [edi]
add esi, 4
add edi, 4
loop ciclo_subtrair
jmp ciclo_maior
;----------------------------------------------------------------------------------------------------------
;
; BLOCO N+1
troca_ou_nao: ; chega aqui com eax=num1 e ebx=num2; deve sair com eax=resultado
; multiplicar somar a variavel guardar edx na outra variavel somar 4 voltar ao inicio
mov eax,[num1+28]
shr eax,31
jz nao_trocar_num1
mov edi,num1
call troca_sinal
nao_trocar_num1:
mov ebx,[num2+28]
shr ebx,31
jz nao_trocar_num2
mov edi, num2
call troca_sinal
nao_trocar_num2:
xor eax,ebx
mov [sinalfinal],eax
cmp dl, '*'
jne nao_salta4
jmp multiplica
nao_salta4:
cmp dl, '/'
jmp divide
multiplica:
mov dword[temp],0
xor edx,edx
clc
; BLOCO N+2
; bloco da multiplicacao
mov eax, [num1]
mov ebx, [num2]
mul ebx
mov [num1],eax
mov [temp],edx
mov eax, [num1+4]
mov ebx, [num2+4]
mul ebx
add eax,[temp]
mov [num1+4],eax
mov [temp],edx
mov eax, [num1+8]
mov ebx, [num2+8]
mul ebx
add eax,[temp]
mov [num1+8],eax
mov [temp],edx
mov eax, [num1+12]
mov ebx, [num2+12]
mul ebx
add eax,[temp]
mov [num1+12],eax
mov [temp],edx
mov eax, [num1+16]
mov ebx, [num2+16]
mul ebx
add eax,[temp]
mov [num1+16],eax
mov [temp],edx
mov eax, [num1+20]
mov ebx, [num2+20]
mul ebx
add eax,[temp]
mov [num1+20],eax
mov [temp],edx
mov eax, [num1+24]
mov ebx, [num2+24]
mul ebx
add eax,[temp]
mov [num1+24],eax
mov [temp],edx
mov eax, [num1+28]
mov ebx, [num2+28]
mul ebx
add eax,[temp]
mov [num1+28],eax
mov eax,[sinalfinal]
cmp eax,0
jz nao_trocar_result
mov edi,num1
call troca_sinal
nao_trocar_result:
jmp ciclo_maior
divide: ; chega aqui com eax=num1 e ebx=num2; deve sair com eax=resultado
SUB EDX, EDX
MOV EAX, esi
MOV EBX, edi
DIV EBX
jmp numero_dois
;BLOCO N+3
;troca o sinal de um dado numero de 256 bits
troca_sinal:
not dword [edi]
not dword [edi+4]
not dword [edi+8]
not dword [edi+12]
not dword [edi+16]
not dword [edi+20]
not dword [edi+24]
not dword [edi+28]
add dword [edi],1
adc dword [edi+4],0
adc dword [edi+8],0
adc dword [edi+12],0
adc dword [edi+16],0
adc dword [edi+20],0
adc dword [edi+24],0
adc dword [edi+28],0
ret