flat assembler
Message board for the users of flat assembler.

Index > Main > Macro: string comparison and sort

Author
Thread Post new topic Reply to topic
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Possible? Would be nice for PE export macro to automatically sort exports alphabetically. Smile

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 18 Feb 2004, 04:52
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
I came with up with this lame integer sort:
Code:
macro sort [val] {
    prev = 0
    min = 0
    count = 0
    forward
      count = count + 1
    common
    repeat count
      common
        min = 0
        xmin val
        prev = min
        db min
    end repeat
}
macro xmin [val] {
    i = 30h
    forward
       i = i + 1
       display i,": ",val,13,10
       if val > prev
         display "    val > prev",13,10
         if min = 0
           min = val
         end if
         if val < min
           display "    val < min",13,10
           min = val
         end if
       end if
}

input:  sort    38h,35h,34h,39h,32h
 db      0    


After running, input will contain "24589"

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 18 Feb 2004, 05:31
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Code:
macro strcmp str1, str2 {
    local ..count,..x,..char1,..char2
    strcmpr = 0
    virtual at 0
        db str1
        ..count = $
    end virtual
    virtual at 0
        db str1
        ..x = $
        db str2
        repeat ..count
            load ..char1 from %-1
            load ..char2 from ..x+%-1
            if strcmpr = 0
                strcmpr = ..char1 - ..char2
            end if
        end repeat
    end virtual
}
macro doshit str1, str2 {
    strcmp str1, str2
    if strcmpr > 0
        db "str1 > str2"
    else if strcmpr < 0
        db "str1 < str2"
    else
        db "str1 = str2"
    end if
}

input:
  doshit "abc","def"
  db 0
    


input will contain "str1 < str2"
now second part - to sort Smile

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 18 Feb 2004, 14:54
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Tommy



Joined: 17 Jun 2003
Posts: 489
Location: Norway
Tommy
Very Happy Cool!
Post 18 Feb 2004, 15:05
View user's profile Send private message Visit poster's website Reply with quote
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
these macros i use for named resource sections. They must be sorted so you can extract the sorting mechanism (it's a bubble sort). It is limited to 7 byte strings!
Code:
macro directory [type,label]
 { common
    local ..c,..i,..j,..l,..m,..s,..t,..idcount,..namecount,..names,..offset
    macro TEMP_RESOURCE_GET c,i,s,l
    m^
     i = ..Temp_ResourceId $$ c
     s = ..Temp_ResourceSize $$ c
     l = ..Temp_ResourceLabel $$ c
    ^m
    macro TEMP_RESOURCE_SET c,i,s,l
    m^
     ..Temp_ResourceId $$ c = i
     ..Temp_ResourceSize $$ c = s
     ..Temp_ResourceLabel $$ c = l
    ^m
    ..c fix 1
    ..namecount = 0
    ..idcount = 0
    if ~<type><label> eq <><>
     forward
      if type eqtype ""
       virtual at 0
        db type
        ..s = $
        times 8 db 0
        ..i = -1
        repeat 7
         load ..j byte from %-1
         ..i = (..i shl 8)+(..j and not 32)
        end repeat
       end virtual
       ..namecount = ..namecount+1
       TEMP_RESOURCE_SET ..c,..i,..s,label
       TEMP_RESOURCE_GET ..c,..i,..s,..l
      else if type eqtype 0
       ..idcount = ..idcount+1
       TEMP_RESOURCE_SET ..c,type,0,label
      end if
      ..c fix ..c#1
     common
      TEMP_RESOURCE_SET ..c,100000000h,..idcount+..namecount+1,0
      repeat ..namecount+..idcount-1
       ..c fix 1
        forward
         TEMP_RESOURCE_GET ..c,..i,..s,..l
         TEMP_RESOURCE_GET ..c#1,..j,..t,..m
         if ..i > ..j
          TEMP_RESOURCE_SET ..c,..j,..t,..m
          TEMP_RESOURCE_SET ..c#1,..i,..s,..l
         end if
         ..c fix ..c#1
        common
      end repeat
      ..ResourceRoot dd 0,%t,0,(..idcount shl 16)+..namecount
      ..names = ..offset-..ResourceRoot
      ..c fix 1
     forward
      TEMP_RESOURCE_GET ..c,..i,..s,..l
      if ..i < 0
       dd 80000000h+..names,80000000h+..l-..ResourceRoot
       ..names = ..names+..s*2+2
      else
       dd ..i,80000000h+..l-..ResourceRoot
      end if
      ..c fix ..c#1
     common
      ..offset:
      ..c fix 1
     forward
      TEMP_RESOURCE_GET ..c,..i,..s,..l
      if ..i < 0
       dw ..s
       ..i = ..i shr ((7-..s)*8)
       repeat ..s
        db ..i shr ((..s-%)*8) and 0FFh
        db 0
       end repeat
      end if
      ..c fix ..c#1
     common
     align 4
    end if
 }

macro resource dir,[id,lang,label]
 { common
    dir:
   forward
    resource_min = id
    resource_max = id
   common
    resource_count = 0
   forward
    local resource_label
    resource_count = resource_count + 1
    if id < resource_min
    resource_min = id
    else if id > resource_max
    resource_max = id
    end if
   common
    dd 0,%t,0,resource_count shl 16
    repeat resource_max-resource_min+1
   forward
    if resource_min+%-1 = id
    dd id,80000000h+resource_label-..ResourceRoot
    end if
   common
    end repeat
   forward
    label#.resid = id
    resource_label dd 0,%t,0,10000h,lang,label-..ResourceRoot }

m^ fix {
^m fix }
_common fix common
_forward fix forward
_reverse fix reverse
_local fix local
$$ fix ^_^
^_^ fix #
    
Post 18 Feb 2004, 17:49
View user's profile Send private message Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Thanks. Why do you have all these fixes for common and reverse, etc at the end?

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 18 Feb 2004, 20:47
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Joshua



Joined: 12 Jul 2003
Posts: 56
Location: Belgium
Joshua
_common, _forward, _reverse and _local are unneeded, the others are. (it was just a copy and paste job)
Post 18 Feb 2004, 21:21
View user's profile Send private message Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Finally, working version:
Code:
macro sort [val] {
    common
        virtual at 0
            definetokens val
            len = $
        end virtual
        repeat len
            virtual at 0
                definetokens val
                shit = % - 1
                pos2idx shit
            end virtual
            if outpos > 0
                virtual at 0
                    vsort outidx,outpos,val
                    load char from outpos
                end virtual
                db char
            end if
        end repeat
}
macro vsort needidx,needpos,[val] {
    common
        definetokens val
        prev = 0
        min = 0
        i = 0
        repeat tokcount
            i = i + 1
            min = 0
            k = 0
            repeat tokcount
                k = k + 1
                if prev = 0
                    strcmpr = 1
                else
                    strcmpidx k,prev
                end if
                if strcmpr > 0
                    if min = 0
                        min = k
                    end if
                    strcmpidx k,min
                    if strcmpr < 0
                        min = k
                    end if
                end if
            end repeat
            prev = min
            if % = needidx
                curpos = 0
                k = 0
                repeat tokcount
                    k = k + 1
                    load curlen from curpos
                    if k = min
                        outpos = curpos + needpos
                    end if
                    curpos = curpos + curlen + 1
                end repeat
            end if
        end repeat
}
macro definetokens [val] {
    tokcount = 0
    forward
        tokcount = tokcount + 1
        strlen val
        db strlenr
        db val
    common
}
macro pos2idx pos {
    k = 0
    tokpos = 0
    outpos = 0
    outidx = 0
    repeat tokcount
        k = k + 1
        load toklen from tokpos
        if pos >= tokpos
            if pos <= (tokpos+toklen)
                outpos = pos - tokpos
                outidx = k
            end if
        end if
        tokpos = tokpos + toklen + 1
    end repeat
}
macro strcmpidx str1,str2 {
    local ..count,..x,..char1,..char2,..pos
    strcmpr = 0
    ..x = 0
    ..pos = 0
    repeat tokcount
        load len from ..pos
        ..x = ..x + 1
        if ..x = str1
            str1pos = ..pos+1
            str1len = len
        end if
        if ..x = str2
            str2pos = ..pos+1
            str2len = len
        end if
        ..pos = ..pos + len + 1
    end repeat
    ..count = str1len
    if ..count > str2len
        ..count = str2len
    end if
    repeat ..count
        load ..char1 from str1pos+%-1
        load ..char2 from str2pos+%-1
        if strcmpr = 0
            strcmpr = ..char1 - ..char2
        end if
    end repeat
}
macro strlen val {
    virtual at 0
        db val
        strlenr = $
    end virtual
}

input:  sort    "abc","def","bbb","zzz","yyy"
        db      0    


input will contain "abcbbbdefyyyzzz"

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 19 Feb 2004, 06:29
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Almost works, needs some change to work with variable length strings. But too late now, I must sleep.

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 19 Feb 2004, 06:36
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Here final version:
Code:
macro sort [val] {
    common
        virtual at 0
            definetokens val
            len = $
        end virtual
        gotlen = 0
        repeat len
            virtual at 0
                needpos = %-1
                vsort needpos,val
                load char from outpos
            end virtual
            if gotlen > 0
                db char
                gotlen = gotlen - 1
            else if gotlen = 0
                gotlen = char
                if % > 1
                    db ","
                end if
            end if
        end repeat
}
macro vsort inpos,[val] {
    common
        definetokens val
        prev = 0
        min = 0
        i = 0
        abspos = 0
        abslen = 0
        repeat tokcount
            i = i + 1
            min = 0
            k = 0
            repeat tokcount
                k = k + 1
                if prev = 0
                    strcmpr = 1
                else
                    strcmpidx k,prev
                end if
                if strcmpr > 0
                    if min = 0
                        min = k
                    end if
                    strcmpidx k,min
                    if strcmpr < 0
                        min = k
                    end if
                end if
            end repeat
            prev = min
            k = 0
            display "min: ",min+30h,13,10
            curpos = 0
            repeat tokcount
                k = k + 1
                load curlen from curpos
                if k = min
                    repeat curlen+1
                        if inpos = abspos
                            outpos = curpos + % - 1
                        end if
                        abspos = abspos + 1
                    end repeat
                    abslen = curlen
                end if
                curpos = curpos + curlen + 1
            end repeat
        end repeat
}
macro definetokens [val] {
    tokcount = 0
    forward
        tokcount = tokcount + 1
        strlen val
        db strlenr
        db val
    common
}
macro pos2idx pos {
    k = 0
    tokpos = 0
    outpos = 0
    outidx = 0
    repeat tokcount
        k = k + 1
        load toklen from tokpos
        if pos >= tokpos
            if pos <= (tokpos+toklen)
                outpos = pos - tokpos
                outidx = k
            end if
        end if
        tokpos = tokpos + toklen + 1
    end repeat
}
macro strcmpidx str1,str2 {
    local ..count,..x,..char1,..char2,..pos
    strcmpr = 0
    ..x = 0
    ..pos = 0
    repeat tokcount
        load len from ..pos
        ..x = ..x + 1
        if ..x = str1
            str1pos = ..pos+1
            str1len = len
        end if
        if ..x = str2
            str2pos = ..pos+1
            str2len = len
        end if
        ..pos = ..pos + len + 1
    end repeat
    ..count = str1len
    if ..count > str2len
        ..count = str2len
    end if
    repeat ..count
        load ..char1 from str1pos+%-1
        load ..char2 from str2pos+%-1
        if strcmpr = 0
            strcmpr = ..char1 - ..char2
        end if
    end repeat
}
macro strlen val {
    virtual at 0
        db val
        strlenr = $
    end virtual
}

input:  sort    "grapefruit","apple","grenade","tangerine","orange","peach"
        db 0
    


input contain "apple,grapefruit,grenade,orange,peach,tangerine" after compilation Twisted Evil Laughing Twisted Evil

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 20 Feb 2004, 04:45
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Slightly modified version:

Code:
macro sort [val] {
    tokcount = 0
    forward
        tokcount = tokcount + 1
    common
        local i, needidx,char,tokpos
        repeat tokcount
            virtual at 0
                definetokens val
                needidx = %
                vsort needidx,val
            end virtual
            i = 0
            tokpos = 0
            repeat tokcount
                i = i + 1
                virtual at 0
                    definetokens val
                    load toklen from tokpos
                end virtual
                if i = outidx
                    repeat toklen
                        virtual at 0
                            definetokens val
                            load char from tokpos+%
                        end virtual
                        db char
                    end repeat
                    db ","
                end if
                tokpos = tokpos + toklen + 1
            end repeat
        end repeat
}
macro vsort inidx,[val] {
    common
        local prev,min,i,k
        prev = 0
        min = 0
        i = 0
        repeat tokcount
            i = i + 1
            min = 0
            k = 0
            repeat tokcount
                k = k + 1
                if prev = 0
                    strcmpr = 1
                else
                    strcmpidx k,prev
                end if
                if strcmpr > 0
                    if min = 0
                        min = k
                    end if
                    strcmpidx k,min
                    if strcmpr < 0
                        min = k
                    end if
                end if
            end repeat
            prev = min
            if i = inidx
                outidx = min
            end if
        end repeat
}
macro definetokens [val] {
    tokcount = 0
    forward
        tokcount = tokcount + 1
        strlen val
        db strlenr
        db val
    common
}
macro strcmpidx str1,str2 {
    local ..count,..x,..char1,..char2,..pos
    strcmpr = 0
    ..x = 0
    ..pos = 0
    repeat tokcount
        load len from ..pos
        ..x = ..x + 1
        if ..x = str1
            str1pos = ..pos+1
            str1len = len
        end if
        if ..x = str2
            str2pos = ..pos+1
            str2len = len
        end if
        ..pos = ..pos + len + 1
    end repeat
    ..count = str1len
    if ..count > str2len
        ..count = str2len
    end if
    repeat ..count
        load ..char1 from str1pos+%-1
        load ..char2 from str2pos+%-1
        if strcmpr = 0
            strcmpr = ..char1 - ..char2
        end if
    end repeat
}
macro strlen val {
    virtual at 0
        db val
        strlenr = $
    end virtual
}    

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 20 Feb 2004, 15:58
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
privalov: another thread to pinpoint on fasm site
Post 21 Feb 2004, 11:29
View user's profile Send private message Visit poster's website AIM Address MSN Messenger 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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.