'NASM - Get a sub-string by cycling a big text
I have this homework in which i have some words from a txt file and, depending on a random number, i must take out one of the words inside, txt file looks like this:
,author0,fear0,dance0,money0,bottle0,pillow0
As you can see there is a ',' before and a '0' after each word. I already have the random number and the import of the file content done and successful, however what i am trying to do to for extract the sub-string and therefore the word, is: looping the whole text content, when it reaches a ',' it compares to know if the counter of ',' appearances is the same as the random number and by then, save the next characters in the buffer variable until finding a '0' so it can return to the start function. I have this code by far:
%include macros.inc ;macros and definition of system calls
%include random.asm ;where the random number is created
section .data
filename: dq "txt/low.txt",10
counter: db 0 ;counts the traveled spaces to know if equals random
random: db 0
section .bss
text resq 18 ;stores all the content in txt file
buffer resb 18;saves the substring looked from text, supposed to be a word
section .text
global _start
_start:
call fileReadingLow ;saves txt file content in 'text' variable
call generateRandomNumber ;saves a random number between 0-9 in 'random'
mov eax,text ;for looping characters in text
mov ecx,48 ;amount of characters in text
call loopWord
print buffer ;macro from macros.inc
exit ;macro
fileReadingLow:
;Open the file
mov rax, SYS_OPEN
mov rdi, filename
mov rsi, O_RDONLY
mov rdx,0
syscall
;Read from file
push rax
mov rdi, rax
mov rax, SYS_READ
mov rsi, text
mov rdx, 128
syscall
;Close file
mov rax, SYS_CLOSE
pop rdi
syscall
ret
loopWord:
push rcx
cmp byte[eax],',' ;if character is a comma
je checkRandom
inc eax
pop rcx
loop checkRandom
checkRandom:
mov ebx,[counter]
cmp ebx,[random]
je getWord ;compare if random equals counter of appearances
inc ebx ;increments counter
mov [counter],ebx
pop rcx ;pop cause it does not reaches this line in loopWord
inc rcx ;same reason as above
jmp loopWord
getWord: ;loop the following characters for adding them to buffer
cmp byte[eax],'0' ;suppossedly last char from the word
je RETURN
mov dl,byte[eax] ;char from text in dl
mov [byte+1],dl ;add the char to buffer
inc eax
jmp getWord
RETURN:
pop rcx
ret
My main problem is that i do not know how to append chars consecutively in my buffer variable, by far it only contains the last character of each word. If someone would know how to do this would solve everything.
Solution 1:[1]
There's more than one error:
,author0,fear0,dance0,money0,bottle0,pillow0
The file has 44 bytes, but your program uses the number 48
filename: dq "txt/low.txt",10
The correct way to write this is filename db "txt/low.txt", 0 using the db directive.
counter: db 0 random: db 0
These are defined as bytes, but your program reads and writes these as dwords!
My main problem is that i do not know how to append chars consecutively in my buffer variable, by far it only contains the last character of each word. If someone would know how to do this would solve everything.
The loopWord code is wrong in many places. I don't see how it can be salvaged!
Let's start by writing a loop that just traverses the file held in text.
; IN (rax,rcx)
loopWord:
mov dl, [rax] ; Fetch current character
...
inc rax ; Move pointer
dec rcx ; Decrement counter
jnz loopWord ; Continue until exhausted
ret
Then we'll start counting commas:
; IN (rax,rcx)
loopWord:
mov dl, [rax]
cmp dl, ','
jne .cont ; Skip if not comma
sub byte [random], 1 ; Produces CF=1 only if random was 0 before
jb .found
.cont:
inc rax
dec rcx
jnz loopWord
ret
.found:
...
Once found the entry, we will copy it to the buffer.
; IN (rax,rcx)
loopWord:
mov dl, [rax]
cmp dl, ','
jne .cont
sub byte [random], 1
jnb .found
.cont:
inc rax
dec rcx
jnz loopWord
ret
.found:
mov ebx, buffer
.next:
mov dl, [rax] ; Read next character from SOURCE
mov [rbx], dl ; Write next character in DESTINATION
inc rax ; Move SOURCE pointer
inc rbx ; Move DESTINATION pointer
cmp dl, '0' ; Continue until '0' was read and written
jne .next
ret
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sep Roland |
