So basically I have this code where I need to check if a word is inside a sentence and I have no clue in how to do it. It's my first week learning assembly sorry. Im making my own sql but in local just to try and so far I have checked if a word is equal to another word but I cant think of a way to detect if it is inside a sentence. In the code I read an archive line by line and then I jmp to "siguiente_palabraDeseado" where I have to search "palabra2" inside "palabraaux".
I just need an example on how to do it.
Thanks in advance and sorry for my english.
Just in case you want to see the whole code(This isnt necessary, just with an example I would be ok) but If you want to try it
section .data
frase db 100 dup(0)
longitud equ 100
palabra1 db 100 dup(0)
palabra2 db 100 dup(0)
palabra3 db 100 dup(0)
palabraAux db 100 dup(0) ;Palabra auxiliar para guardar la de los archivos
fraseAux db 100 dup(0) ;Frase auxiliar para guardar la de los archivos
error db "No se pudo abrir el archivo.", 10
errorLen equ $ - error
error2 db "No se pudo leer el archivo.", 10
errorLen2 equ $ - error2
error3 db "Orden no encontrada.", 10
errorLen3 equ $ - error3
error4 db "Archivo cerrado incorrectamente.", 10
errorLen4 equ $ - error4
saltoLinea db 10,0
select db "select",0
insert db "insert",0
exitText db "exit",0
todo db "*",0
prueba db "Llego hasta aqui",10 ;para poder hacer debug
pruebaLen equ $ - prueba
section .bss
fileIdentificator resb 100
content resb 4096
section .text
global _start
_start:
mov ecx, 100 ; Cantidad de bites a limpiar
; Limpiar palabra1
mov edi, palabra1 ; Dirección base de palabra1
xor eax, eax ; Valor cero
rep stosb ; Almacenar valor cero en ecx bytes desde edi
; Limpiar palabra2
mov edi, palabra2 ; Dirección base de palabra2
xor eax, eax ; Valor cero
rep stosb ; Almacenar valor cero en ecx bytes desde edi
; Limpiar palabra3
mov edi, palabra3 ; Dirección base de palabra3
xor eax, eax ; Valor cero
rep stosb ; Almacenar valor cero en ecx bytes desde edi
; Limpiar fileIdentificator
mov edi, [fileIdentificator] ; Dirección base de fileIdentificator
mov eax, 0 ; Valor cero
rep stosb ; Almacenar valor cero en ecx bytes desde edi
; Limpiar palabra auxiliar
mov edi, palabraAux ; Dirección base de fileIdentificator
xor eax, eax ; Valor cero
rep stosb ; Almacenar valor cero en ecx bytes desde edi
; nuevaLinea
mov eax, 4
mov ebx, 1
mov ecx, saltoLinea
mov edx, 2
int 80h
; nuevaLinea
mov eax, 4
mov ebx, 1
mov ecx, saltoLinea
mov edx, 2
int 80h
; Leer la frase ingresada por el usuario
mov eax, 3 ; Número de llamada al sistema para leer
mov ebx, 0 ; Descriptor de archivo (stdin)
mov ecx, frase ; Puntero al búfer de entrada
mov edx, longitud ; Longitud máxima de entrada
int 80h ; Llamar al sistema operativo
; Inicializar los registros
mov ebx, 0 ; Indicador de posición en la frase
mov ecx, 0 ; Indicador de posición en la palabra
mov edi, palabra1 ; Dirección de la primera palabra
recorrer_frase:
; Verificar si hemos llegado al final de la frase
cmp ebx, longitud
jge siguiente_palabra
; Obtener el carácter actual
mov al, [frase + ebx]
; Verificar si es un espacio en blanco
cmp al, ' '
je siguiente_palabra
; Almacenar el carácter en la palabra correspondiente
mov [edi + ecx], al
; Incrementar el contador de posición en la palabra
inc ecx
jmp siguiente_caracter
siguiente_caracter:
; Incrementar el contador de posición en la frase y continuar recorriendo
inc ebx
jmp recorrer_frase
siguiente_palabra:
; Verificar si ya se ha almacenado la primera palabra
cmp edi, palabra1
je almacenar_palabra2
cmp edi, palabra2
je almacenar_palabra3
cmp edi, palabra3
jmp fin
fin:
; Inicializar registros
mov ecx, 0 ; contador
mov esi, palabra1
mov edi, select
comparar_caracteres:
; vamos conparando las letras
mov al, [esi + ecx]
cmp al, [edi + ecx]
jne comprobarInsert ; si no es un select saltamos a comprobar si es un insert
; Verificar si se llegó al final de los strings
cmp al, 0
je selectDone ;input == select
; Incrementar contador y continuar comparando
inc ecx
jmp comparar_caracteres
comprobarInsert:
; Inicializar registros
mov ecx, 0 ; contador
mov esi, palabra1
mov edi, insert
comparar_caracteresInsert:
; vamos comparando las letras
mov al, [esi + ecx]
cmp al, [edi + ecx]
jne comprobarExit ; si no es un insert pasamos a comprobar si es un exit
; Verificar si se llegó al final de los strings
cmp al, 0
je insertDone ;input == insert
; Incrementar contador y continuar comparando
inc ecx
jmp comparar_caracteresInsert
insertDone:
; seleccionamos la palabra y su longitud
mov ecx, palabra3
mov eax, 5
; Añadir la extension basandonos en el lenght
; podriamos añadir byte a byte (inc eax)
mov byte [ecx+eax-1], "."
mov byte [ecx+eax], "t"
mov byte [ecx+eax+1], "x"
mov byte [ecx+eax+2], "t"
add eax,4 ;añadimos a la longitud los 4 bytes extra
;que hemos añadido
; El sistema operativo espera que las cadenas de texto
; acaben en un byte nulo
; Añadir al nombre de archivo con un byte nulo
mov byte [ecx+eax-1], 0
jmp abrirArchivo
comprobarExit:
; Inicializar registros
mov ecx, 0 ; contador
mov esi, palabra1
mov edi, exitText
comparar_caracteresExit:
; vamos comprobando las letras
mov al, [esi + ecx]
cmp al, [edi + ecx]
jne ordenNoEncontrada ; en caso de que no sea exit ni insert ni select mandamos mensajito al usuario
; Verificar si se llegó al final de los strings
cmp al, 0
je exit ;input == exit
; Incrementar contador y continuar comparando
inc ecx
jmp comparar_caracteresExit
selectDone:
;Preparar el input para poder abrir el archivo
mov ecx, palabra3
mov eax, 5
; Añadir la extension basandonos en el lenght
; podriamos añadir byte a byte (inc eax)
mov byte [ecx+eax-1], "."
mov byte [ecx+eax], "t"
mov byte [ecx+eax+1], "x"
mov byte [ecx+eax+2], "t"
add eax,4 ;añadimos a la longitud los 4 bytes extra
;que hemos añadido
; El sistema operativo espera que las cadenas de texto
; acaben en un byte nulo
; Añadir al nombre de archivo con un byte nulo
mov byte [ecx+eax-1], 0
jmp abrirArchivo
almacenar_palabra2:
; sobreescribimos el puntero al registro1 por el registro 2
; Inicializar los registros
mov ecx, 0 ; Indicador de posición en la palabra
mov edi, palabra2 ; Dirección de la segunda palabra
jmp siguiente_caracter
almacenar_palabra3:
; sobreescribimos el puntero al registro 2 por el registro 3
; Inicializar los registros
mov ecx, 0 ; Indicador de posición en la palabra
mov edi, palabra3 ; Dirección de la tercera palabra
jmp siguiente_caracter
;<<<<<<<<<<<<<<<<<MANEJO DE ARCHIVOS>>>>>>>>>>>>>>>>>
abrirArchivo:
;call nuevaLinea
mov eax, 4
mov ebx, 1
mov ecx, saltoLinea
mov edx, 2
int 80h
; Abrir el archivo en modo lectura
mov eax, 5
mov ebx, palabra3
mov ecx, 0
mov edx, 0
int 80h
test eax, eax
js errorOpen_handling
mov [fileIdentificator], eax ; Guardar el descriptor
; Leer el contenido del archivo
mov eax, 3
mov ebx, eax
mov ecx, content
mov edx, 4096
int 80h
test eax, eax
js errorReading_handling
; Mostrar el contenido del archivo
;mov eax, 4
;mov ebx, 1
;mov ecx, content
;int 80h
; Cerrar el archivo
mov eax, 6
mov ebx, [fileIdentificator]
int 80h
test eax,eax
js errorClosing_handling
;<<<<<<<<Aqui empezamos la comprobacion de que devolver>>>>>>>>
; Inicializar registros
mov ecx,0
mov esi, palabra2
mov edi, todo
comparar_caracteresPalabra2:
; vamos comparando las letras
mov al, [esi]
cmp al, [edi]
jne imprimirSoloDeseado ; comprobar si es "*"
;En este caso no nos hace falta contador
;ya que "*" solo tiene un byte
; Mostrar el contenido del archivo
mov eax, 4
mov ebx, 1
mov ecx, content
int 80h
jmp _start
imprimirSoloDeseado:
; Inicializar los registros
mov ebx, 0 ; Indicador de posición en la frase
mov ecx, 0 ; Indicador de posición en la palabra
mov edi, palabraAux ; Dirección de la primera palabra
recorrer_fraseDeseado:
; Verificar si hemos llegado al final de la frase
cmp ebx, longitud
jge siguiente_palabraDeseado
; Obtener el carácter actual
mov al, [content + ebx]
; Verificar si es un espacio en blanco
cmp al, ";"
je siguiente_palabraDeseado
; Almacenar el carácter en la palabra correspondiente
mov [edi + ecx], al
; Incrementar el contador de posición en la palabra
inc ecx
jmp siguiente_caracterDeseado
siguiente_caracterDeseado:
; Incrementar el contador de posición en la frase y continuar recorriendo
; call debug
inc ebx
jmp recorrer_fraseDeseado
siguiente_palabraDeseado:
; el regitro se queda en palabraaux
; comprueba que palabra 2 esta dentro
; de palabraaux en ese caso imprime palabraaux
jmp _start
exit:
; Salir del programa
mov eax, 1
mov ebx, 0
int 80h
;subrutina
debug:
push eax
push ebx
push ecx
push edx
mov eax, 4 ; Número de llamada al sistema para escribir
mov ebx, 1 ; Descriptor de archivo (stdout)
mov ecx, prueba ; Puntero al mensaje
mov edx, pruebaLen ; Longitud del mensaje
int 80h ; Llamar al sistema operativo
; restauramos desde la pila
pop edx
pop ecx
pop ebx
pop eax
ret
;<<<<<<<<<<<Apartado para errores>>>>>>>>>>>
ordenNoEncontrada:
mov eax, 4
mov ebx, 2
mov ecx, error3
mov edx, errorLen3
int 80h
jmp _start
errorOpen_handling:
mov eax, 4
mov ebx, 2
mov ecx, error
mov edx, errorLen
int 80h
jmp _start
errorClosing_handling:
mov eax, 4
mov ebx, 2
mov ecx, error4
mov edx, errorLen4
int 80h
jmp _start
errorReading_handling:
mov eax, 4
mov ebx, 2
mov ecx, error2
mov edx, errorLen2
int 80h
jmp _start
My favourite algorithm uses repeated string operations SCASB and CMPSB. When the first letter of searched Word is found, compare the rest of Word and if it doesn't match, restore pointer in Sentence and continue with the rest.
section .data
SentenceSize DD 27
WordSize DD 3
Sentence DB "guardar la de los archivos."
Word DB "los"
section .text
LEA EDI,[Sentence]
LEA ESI,[Word]
MOV ECX,[SentenceSize]
LODSB ; Load the 1st letter of Word. ESI points at "os".
Search: REPNE SCASB ; Search for the 1st letter of Word ("l").
JNE NotFound
; We have found 1st "l". EDI points at the following "a", ECX=18.
PUSH ESI
PUSH EDI
PUSH ECX
MOV ECX,[WordSize]
DEC ECX ; The first letter of Word is already checked.
REPE CMPSB ; Set ZF=1 when the Word was found.
POP ECX ; Restore the remaining Sentence size (18).
POP EDI ; Restore Sentence pointer after "l".
POP ESI ; Restore Word pointer to "os".
JNE Search ; If ZF=0, search for "l" again. 2nd time it will succeed.
Found: ; The Word was found in Sentence at the address EDI-1.
NotFound:; The Word is not present in Sentence.