Hi, some beginner's questions here:
1.Why does it work
fopen("c:\the\path\to\file.txt")
and this doesn't
fpath db "c:\the\path\to\file.txt", 0
fopen(fpath)
and how to make that work? It seems like it wants a value; address doesn't work either.
2. How do I use (write/read) an array of strings (of diffrent length)? And array of arrays of strings (not rectangle)?
Also considering case when I have a big file of strings loaded and I want to make such array only for indexing/addressing them instead of copying.
3. What are the ways to load file and when are they prefered and when not.
4. Is it a bug that arrfile$ doesn't load files from another disk?
5. Any shortcuts for fast compile/run program?
6. How to print variables/registers?
7. And btw how does it work that when I pass a string or array (well, the same) somewhere it knows the length of it? Since i guess it just sends a single number of its address.
8. And then how do I know the length of an array, including case in question 2. ?
I know the answers should be in examples/tutorials folders but when I try get them work at my own they doesn't.
1. fopen(offset fpath)
2. Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) "somefile.txt", my$()
There is also the masm32 macro ltok.
3. What are the ways to load file and when are they prefered and when not.
Many!
4. Is it a bug that arrfile$ doesn't load files from another disk?
Full correct path?
5. Any shortcuts for fast compile/run program?
In RichMasm (http://masm32.com/board/index.php?topic=5314.0), hit F6. Works also with non-MasmBasic sources.
6. How to print variables/registers?
Print Str$("This is eax: %i\n", eax)
or
deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) "some test", eax, xmm0, MyDword, al, ax, ST(1), ... whatever you need for debugging
7. And btw how does it work that when I pass a string or array (well, the same) somewhere it knows the length of it? Since i guess it just sends a single number of its address.
Either zero-delimited, or len is stored somewhere.
8. And then how do I know the length of an array, including case in question 2. ?
Recall returns the #strings in eax. Afterwards,
Print Str$("The array My$() has %i elements", My$(?))
I know the answers should be in examples/tutorials folders but when I try get them work at my own they doesn't.
Come up with concrete code and questions, and we'll help you.
This one is an easy one.
fpath db "c:\the\path\to\file.txt", 0
fopen(fpath)
"fpath" is an entry in the uninitialised data section, you normally use "OFFSET fpath" to get its address.
1. I tried offset and that didn't work, although I was taking argument of procedure which apparently isn't the same as what I wrote. So then how to do this:
afunc proc filePath:byte
fopen(filePath)
ret
afunc endp
4. I did some more tests and it turned out that it crashes in depend of file content, especially number of lines, thought i can bet that that wasn't working with the same file on diffrent disks (with copyied paths for concurrence). Code:
local hFile:dword
local bwrt:dword
local flen:dword
local hMem:dword
local hArr:dword
;"C:\users\w\desktop\test.txt" ;paths to both files (of the same content),program running from C
;"F:\a\test.txt"
mov hFile, fopen("F:\a\test.txt")
mov flen, fsize(hFile)
mov hMem, alloc(flen)
mov bwrt, fread(hFile,hMem,flen)
fclose hFile
print chr$("file content: ")
print hMem,13,10
print chr$("fopen ok", 13, 10, 13, 10)
mov hArr, arrfile$("F:\a\test.txt")
print chr$("file content: ")
print arrget$(hArr,1),13,10 ; 1-based? why?
print chr$("arrfile ok", 13, 10)
And do the arrget$ returns a array of lines? That would be really handy for me.
For the task you have in mind, the "ltok" (line tokenise) procedure is the right one to use. Look up how to use it in the help file. It is a genuinely fast tokeniser and it performs the task in place. Note that it modifies the original string so if you need to preserve the original, make a copy to modify.
Well, what I want to do is load file (~3mb) of words (one per line), and sort it by lenght, so I can reference them like allWords[length][indexOfWordOfThatLength].
That doesn't metter nowadays but it would be nice if i haden't to copy them and therefore double memory usage.
What i thing i have to do is create global array of length e.g. 20 (i haven't longer word), loop through all the words, count how many i have of each length, create subarrays inside the global of that length, then loop again and assing words to correct subarrays.
Btw, I have no idea how to start with all that arraying, lengthing, indexing and referencing.
(Isn't that something for another thread?)
Quote from: MCpiroman on May 04, 2017, 04:37:42 AMWell, what I want to do is load file (~3mb) of words (one per line), and sort it by lenght
Something like this?
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Recall "\Masm32\include\Windows.inc", L$() ; load 26900 lines
For_ ecx=0 To eax-1
Let L$(ecx)=Str$("%000i\t", Len(L$(ecx)))+L$(ecx) ; e.g. 0013 CLIPDATA ENDS
Next
QSort L$() ; short strings on top
.While 1
.Break .if dword ptr [L$(0)]!="0000" ; eliminate all nullstrings
Delete L$(0)
.Endw
Store "SortedByLength.txt", L$() ; save modified array to disk
Inkey "View the file? (y)"
.if eax=="y"
ShEx "SortedByLength.txt" ; ShellExecute with Notepad or similar
.endif
EndOfCodeReading, sorting and saving to disk takes about 60 ms on my Core i5 machine. Strangely enough, it takes only 40 ms to sort a 4MB bible.txt, from a short 12 char "Jesus wept." to a line with 529 characters ::)
@up
Wow, that's some high level stuff. Though, by sort i rather meant to 'segregate'. I mean to make an array of arrays of strings (also arrays) where in each sub array there are only strings of length of this array's index(or + 1).
Example:
From file:
on
a
that
nose
at
you
i
worm
...
make something like:
[
[a, i, o]
[on, to, at, up, me, us]
[one, you, jar, rat]
[nose, core, masm, heat, code, worm, that, make]
]
(just graph, don't want to save it anywhere)
and be able to access from code e.g. 'up' by theWords[1,3] and 'worm' by theWords[3,5]. And also get that length of theWords[0] is 3, and theWords[3] is 8 (there are 8 words of length = 4 (= 3+1))
Aaand then, that the 3'th char of 'worm' is 'r' so it would be theWords[3, 5, 2] = 'r'
I'd like to rather do it by myself, just want to know the way to make that arraying work.
What is the purpose of the exercise? A text compressor?
I'm trying to rewrite my c# text encrypter (or maybe encoder) in assembler to learn it and see the difference in preformance.
Here is a test piece that loads a file and parses it into an array of words. You must remove and single and double quotes as this algo does not enter quoted text. It is so fast that it barely registers a timing. On my dev box I keep getting 15ms for a 4.5 meg file.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL hMem :DWORD
LOCAL pArr :DWORD
LOCAL wCnt :DWORD
LOCAL cntr :DWORD
LOCAL tcnt :DWORD
push esi
push edi
; ----------------------------------------
; benchmark file load & word parser "wtok"
; ----------------------------------------
invoke GetTickCount
push eax
mov hMem, InputFile("warpeace.txt") ; <<<< change this to your own text file
invoke wtok,hMem,ADDR pArr
mov wCnt, eax
invoke GetTickCount
pop ecx
sub eax, ecx
print str$(eax)," Milliseconds",13,10
inkey
; ----------------------------------------
; -----------------
; display the words
; -----------------
mov esi, pArr
mov edi, wCnt
sub edi, 1
mov cntr, -1
@@:
add cntr, 1
invoke StdOut, [esi]
invoke StdOut, chr$(13,10)
add esi, 4
cmp cntr, edi
jb @B
; -----------------
free hMem
pop edi
pop esi
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start