flat assembler
Message board for the users of flat assembler.

Index > Main > Array of structure

Author
Thread Post new topic Reply to topic
n0p



Joined: 06 Jan 2004
Posts: 10
Location: Russia,Novosibirsk
n0p 09 Feb 2004, 18:13
Hi, all! I've got a problem. I have a structure such as
Code:
struc SS Val1, Val2, Val3 {
   .val1 dd Val1
   .val2 dd Val2
   .val3 dd Val3
}    

How can I do an array of this structure with 25 elements?
Post 09 Feb 2004, 18:13
View user's profile Send private message ICQ Number Reply with quote
Tommy



Joined: 17 Jun 2003
Posts: 489
Location: Norway
Tommy 09 Feb 2004, 18:30
This is already discussed several times on this forum, so please browse the board... Recently, it was discussed here: http://board.flatassembler.net/topic.php?t=957&highlight=array+structure. Wink
Post 09 Feb 2004, 18:30
View user's profile Send private message Visit poster's website Reply with quote
n0p



Joined: 06 Jan 2004
Posts: 10
Location: Russia,Novosibirsk
n0p 09 Feb 2004, 18:47
Thanx! Sorry, but I've very bad connection and search simply cann't run...

_________________
English isn't my native, so sorry for any mistakes I can make...
Post 09 Feb 2004, 18:47
View user's profile Send private message ICQ Number Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 09 Feb 2004, 22:46
It seems this question really qualifies for the FAQ - I have just added it there.
Post 09 Feb 2004, 22:46
View user's profile Send private message Visit poster's website Reply with quote
Bitdog



Joined: 18 Jan 2004
Posts: 97
Bitdog 10 Feb 2004, 03:48
I'm no Fasm expert, BUT
what about, a structure with no elements ?

struc mySS {
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(etc to 25 or what ever)
}

then an EQU file
VAL1 = 0
VAL2 = 4
VAL3 = 8
etc untill 25, which are the offsets of the offset,
I don't know how to use them, but I think it's kind like this

mySS NAME

then to access info in a defined/expanded struc

MOV EAX,[NAME+VAL3] ;add the offsets & you've got your DS:offset address

All of that junk is exactly what a struct does anyway ?
Untested idea, so you debug & make it happen or not.
I hope that helps some how.

Reguards
Post 10 Feb 2004, 03:48
View user's profile Send private message Reply with quote
n0p



Joined: 06 Jan 2004
Posts: 10
Location: Russia,Novosibirsk
n0p 12 Feb 2004, 06:34
I make an array of structure:
Code:
    struc gene {
        .alleles          rd                  4
        .fitness         dd                  ?
        .liklelihood    dd                  0.0
    }
    struct gene

    population          rb                  MAXPOP*sizeof.gene
    

But how I can get acces to any element? I do:
Code:
    lea     eax,[population+ecx*sizeof.gene]   <-- Invalid Address
    mov     edx,[eax+gene.fitness]
    

but it doesn't work! Why?

_________________
English isn't my native, so sorry for any mistakes I can make...
Post 12 Feb 2004, 06:34
View user's profile Send private message ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 12 Feb 2004, 07:10
n0p wrote:

But how I can get acces to any element? I do:
Code:
    lea     eax,[population+ecx*sizeof.gene]   <-- Invalid Address
    mov     edx,[eax+gene.fitness]
    

but it doesn't work! Why?


Hi.
It's a problem of the processor, not of the FASM.
Possible addressing modes of x86 processors are:
[reg32+c2*reg32+offset] where every element inside thebrackets is optional and c2 is a constant and may have values: 1, 2, 4 or 8.
So, in your case, if sizeof.gene is inside this values you may write:
lea eax, [population+ecx*sizeof.gene]
Even if the sizeof.gene is inside the values: 3, 5, 9 you still may use addressing mode like above and FASM will convert it to:
lea eax, [population+ecx+ecx*(sizeof.gene-1)]

But in your case you have sizeof.gene too big (it is 24 bytes long). The only possible solution is:
Code:
    mov    eax, ecx
    imul    eax, sizeof.gene
    lea    eax, [population+eax]  ; to get the begining of the element
;or
    lea    eax, [population+eax+gene.fitness]  ; to get some field of the structure

; imul is slow if you use it inside inner loop, so sometimes you may prefer solution with avoiding imul:

  mov  eax, ecx
  shl   eax, 1
  add  eax, ecx  ; eax = 3*ecx
  lea   eax, [population+8*eax]   ; it is only if the sizeof.gene=24
    


Regards.
Post 12 Feb 2004, 07:10
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Bitdog



Joined: 18 Jan 2004
Posts: 97
Bitdog 12 Feb 2004, 09:03
Heres a couple of new ways to look at a struc.

Use a memory buffer some where and load a data base file to it.
The Dbase file, has it's fields filled with name,address,town,etc
Your program refers to the buffer as/at DS:DBASE
You have an EQU file to address the fields in the buffer DS:DBASE

NAMEfirst = 0 ;zero is never needed
NAMEmiddle = 16 ;maximum length of first name = start adr of this field
NAMElast = 32 ;length of first+middle name = adr of this field, always maximum possible length of any field added up.
continue untill all fields have an address according to their alloted size.
STRUClength = length of the entire data structure,
& is used to move to (address) the next Dbase name/PERSON.

MOV ESI,DBASE+(STRUClength*5) ; gets ESI to the offset address of the 5th person.

Since maximum length of each field is = to the longest name/character_count for that field in the entire data base
data base files are bloat ware to the max, but there is another way.
---------------------------------------------------------------------
CALL LOADdBASE ; PROC
loads a non bloat ware Dbase file into memory,
then converts that to fields of a set length according to the struct field EQU file = std struc Dbase addressing.
The DBASE INfile consists of a field divider character and an end of struct character.
Fields can be filled or left blank.
The LOADdBASE proc, loads the entire file to temporary memory,
then parces it to a memory buffer where it's used and addressed
parcing using the EQU offset & STRUClength definitions to create a normal Dbase with fields of a set length.
I made one this way and it worked fine.
I used CRLF = 13,10 for the end of struc/person character because I used an ascii editor
and it viewed just like a regular text file that way.
It could be line searched via STR.COM my line searcher
which searches a file & writes lines with string in it to OUTfile. (which is the quickest DataBase search there is)
Then STRNOT.COM would remove unwanted lines by finding every line that string was NOT in & writing to OUTfile.
But a .doc style with end of field = 10 = LF would be just fine too. (and save one byte per line/struct/person in Dbase file size)
For viewing and easy typing in my Dbase test I used a (space,*,space)
to seperate the fields because no data in any field used the * character
and it was easy to see as a seperator when the Dbase file was viewed by a std ascii file viewer program.
Then my LOADdBASE proc just simply wrote/movsb untill * to fill a field from temp mem to a std Dbase type memory buffer,
Then loaded the next field the same way,
upon finding a 13 or 10 CRLF
it moved to write the next PERSON or struct adr (STRUClength)
continue write/move untill end of file/temp_buffer.
The loading is slow in the respect that it had to decifer the Dbase file in memory,
but loading the Dbase INfile was fast in the respect that it was 1/3 the size.
So time worked out to be about the same.
The Dbase file was viewable, string searchable, & considerable smaller.

Bitdog
PS, forgive me, but I don't have a usable spell checker & I make lots of mistakes.
Post 12 Feb 2004, 09:03
View user's profile Send private message Reply with quote
n0p



Joined: 06 Jan 2004
Posts: 10
Location: Russia,Novosibirsk
n0p 12 Feb 2004, 09:42
Thanks to all for help! Very Happy

_________________
English isn't my native, so sorry for any mistakes I can make...
Post 12 Feb 2004, 09:42
View user's profile Send private message ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 12 Feb 2004, 10:23
Bitdog wrote:
Heres a couple of new ways to look at a struc.

Use a memory buffer some where and load a data base file to it.
The Dbase file, has it's fields filled with name,address,town,etc
Your program refers to the buffer as/at DS:DBASE
You have an EQU file to address the fields in the buffer DS:DBASE

NAMEfirst = 0 ;zero is never needed
NAMEmiddle = 16 ;maximum length of first name = start adr of this field
NAMElast = 32 ;length of first+middle name = adr of this field, always maximum possible length of any field added up.
continue untill all fields have an address according to their alloted size.
STRUClength = length of the entire data structure,
& is used to move to (address) the next Dbase name/PERSON.

MOV ESI,DBASE+(STRUClength*5) ; gets ESI to the offset address of the 5th person.



Hm, actually I can't agree with such approach. You make manually the things that FASM will do automatically for you. Why? Here is IMHO, the same, but more structured:

Code:
struc TDBRecord {
  .NAMEfirst  rb 16
  .NAMEmiddle rb 16
  .NAMElast   rb 16
}
struct TDBRecord

; Now you have following labels/values automatically created by FASM
;
; TDBRecord.NAMEfirst = 0
; TDBRecord.NAMEmiddle = 16
; TDBRecrod.NAMElast = 32
; sizeof.TDBRecord = 48
;
; if you later change TDBRecord definition, this values will be
; adjusted acordingly.

; Lets now make some processing:

        stdcall ReadDataBase, dbFileName ; reads database in memory unpack it.
                                         ; returns eax - memory pointer to the buffer.
                                         ;         ecx - count of rows in database.

        mov     esi, eax ; the base pointer to database.

        lea     edi, [esi+75*sizeof.TDBrecord] ; a pointer to 75-th element.
        stdcall ProcessRecord, edi

; Lets enumerate all elements and to pass pointers to each element to
; the subroutine ProcessRecord
        xor     edi, edi
.loop:
        lea     eax, [esi+edi]
        stdcall ProcessRecord, eax
        add     edi, sizeof.TDBRecord
        loop    .loop
    


The advantage of the above example is that if you decide to change the format of the record, you have to edit only definition of the structure, nothing else. Also imagine that you have hundreds of structures in your program. If you use above approach, the offsets of the fields for every structure will be separated as local labels of the structure name, not as absolute constants.

Regards.
Post 12 Feb 2004, 10:23
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Bitdog



Joined: 18 Jan 2004
Posts: 97
Bitdog 13 Feb 2004, 03:38
Hello JohnFound,
I will anilize your post, & thank you for the info.
(Your coding & comments are beautiful.)

I throw out ideas to see if they fly or not.
I'm not an expert by any means.

I realize the cheepo+struc idea is flawed & nonstandard.
BUT, take a nuttly idea, mix it with another nutty idea,
look at a problem a different way & something good comes of it sometimes.
It's happened that way in the past alot.
I'll contribute the nutty ideas & count on you guys for the rest. Smile

Your name sounds very familuar, I believe you've helped me in the past.
.doc's, downloads, ?, somewhere? Thankx.

Bitdog
Post 13 Feb 2004, 03:38
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 13 Feb 2004, 07:14
Bitdog wrote:
Your name sounds very familuar, I believe you've helped me in the past. .doc's, downloads, ?, somewhere?


Well, I was a participator in several delphi forums a few years ago, and now I am joined to other asm forums too. Also there are around several of my old Delphi programs: "SpaceGlyph" and "SpaceText"... Anyway, you are always welcome.

Regards.
Post 13 Feb 2004, 07:14
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.