flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Is in fasmg any operations to perform string compare?

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 806
Location: Russian Federation, Sochi
ProMiNick 20 Oct 2016, 10:16
Code:
;here compared not strings itself but their int representations in LE order.
if +'abcdef' < +'b' ;actualy compares string 'fedcba' with string 0#0#0#0#0#'b'    


Needed sm operator like this:

Code:
if swap (+'abcdef'+'abcdef'+'b') < swap (+'b'+'abcdef'+'b')     


Or Is it realized in fasmg any other way?

operators locase upcase & length would be prefered too.
Can be swap & length operators realized natively not with macro?

Thnx.

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 20 Oct 2016, 10:16
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 20 Oct 2016, 10:28
ProMiNick wrote:
Code:
;here compared not strings itself but their int representations in LE order.
if +'abcdef' < +'b' ;actualy compares string 'fedcba' with string 0#0#0#0#0#'b'    

This compares the strings exactly:
Code:
if 'abcdef' eq 'b'    
This actual line even works the same as in fasm 1, even though EQ works a bit differently in fasmg in general.

PS. While testing some examples now I discovered a small bug in the EQ implementation, I'm going to fix it soon.
Post 20 Oct 2016, 10:28
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 20 Oct 2016, 10:50
I have uploaded the fixed version (hl4ld), here is the test case that checks the difference between = and EQ in the aspect where the bug was present:
Code:
virtual
        dd 0
        load string_of_zeros:4 from $$
end virtual

assert string_of_zeros = ''

assert ~ string_of_zeros eq ''    

As for the dedicated operators for string values, I predicted that I would one day add some, but I have not invented a syntax for them yet.
Post 20 Oct 2016, 10:50
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 806
Location: Russian Federation, Sochi
ProMiNick 20 Oct 2016, 14:59
Equal & unequal are not matter for string sorting.
For me it is normal to convert string to int before comparison.
My problem is absense of swap operator, it can be named BELE or LEBE, that switches from BigEndian to LittleEndian and viceversa.
syntax:
BELE value
or
LEBE value
precedence same as not

Code:
swap_term_value_bytes:
; in:
;  edi - ExpressionTerm
; out:
;  zf set if result is zero
; preserves: esi, edi
        mov     [destination_term],edi ;+
        call    get_numeric_term_value ;+
        mov     esi,edx                ;+
        mov     edi,[value_position]   ;+
        add     edi,[value_workspace.memory_start] ;+
        mov     ecx,[esi]              ;+
        add     ecx,4                  ;4-not|5-neg
        mov     edx,value_workspace    ;+
        call    reserve_workspace      ;+
        jnc     pointers_ready_for_swap_bytes   ;+
        mov     edi,[destination_term] ;+
        call    get_term_value         ;+
        mov     esi,edx                ;+
        mov     edi,[value_position]   ;+
        add     edi,[value_workspace.memory_start] ;+
      pointers_ready_for_swap_bytes:;+
        mov     edx,[esi]              ;+
        xor     ecx,ecx
        test    edx,edx
        jz      swap_zero
        add     esi,edx                ; is it correct?
        add     esi,4
        add     edi,4
      swap_bytes:
        cmp     ecx,edx
        je      bytes_swaped
        mov     al,[esi-ecx]
        mov     [edi+ecx],al
        inc     ecx
        jmp     swap_bytes
      bytes_swaped:
        sub     edi,4
        mov     [edi],ecx
        jmp     value_finished
      swap_zero:
        inc     ecx
        mov     [edi],ecx
        mov     cl,[esi+4]
        mov     [edi+4],cl
        jmp     value_finished 
    
Post 20 Oct 2016, 14:59
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 20 Oct 2016, 15:12
For a numeric BSWAP-value, specifying the length of the value is a crucial matter. When do you a BSWAP of value "1", the result is different depending on whether it is 32-bit or 64-bit BSWAP (or a different one altogether, if we think outside x86). So the only way to implement BSWAP for numeric values would be make it an operator with two arguments (like "value BSWAP 4").

On the other hand, reversing the order of bytes in a string is possible without additional information, but this is a different and quite unusual operation. It is unusual enough that I would only recommend implementing it with macros, especially in case of fasmg where the "go with macro" stance is really the default one.
Post 20 Oct 2016, 15:12
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20461
Location: In your JS exploiting you and your system
revolution 20 Oct 2016, 15:21
ProMiNick wrote:
... absense of swap operator, it can be named BELE or LEBE ...
... or byte_reversal, which is what it is actually doing. It can be interpreted as a change of endian, but that is not the basic underlying operation. Intel calls it BSWAP, ARM calls it REV{16|32|64}.
Post 20 Oct 2016, 15:21
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 806
Location: Russian Federation, Sochi
ProMiNick 20 Oct 2016, 15:58
BSWAP -easy to realize as macro with BELE
macro BSWAP val,sz
val = BELE val
val= val shl (sz-(bsr val)+7)/8)*8)
end macro

But BELE is not realizable with BSWAP
Post 20 Oct 2016, 15:58
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 20 Oct 2016, 16:05
ProMiNick wrote:
But BELE is not realizable with BSWAP
It could be just as simple:
Code:
val = val BSWAP (strlen val)    
Though there is no such STRLEN operator in fasmg, but if we assume that a string does not contain a null bytes, the length can be calculated with BSR:
Code:
val = val BSWAP ((bsr (val) shr 3 + 1) shl 3)    

And I'm with revolution that BELE/LEBE name that you used is a bit misleading. The reversal of bytes in a string has nothing to do with endianness. Also, such operation would have to only allow string arguments - for your BSWAP macro to make sense you would need to cast the argument to string first.

Also, BSWAP should actually detect an "out of range" error.
Post 20 Oct 2016, 16:05
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 26 Oct 2016, 22:12
I have added the LENGTHOF and BSWAP operators in fasmg (version hld82).

The LENGTHOF retrieves the length of a string (I chose this name instead of STRLEN because it better fits the naming conventions fasmg uses and is less likely to cause conflicts). This operator is preferable to BSR in case of strings, because it works correctly even when string contains some zero bytes at the end.

The BSWAP works like I proposed above (I've chosen the x86-derived name because fasmg already used the same convention with SHL/SHR/BSR/BSF). The second argument specifies the number of bytes of the [big endian] result, and the result is always a string of this length. The "out of range" error is signaled when the first argument is numerically too large to fit into given number of bytes.

The byte reversal of any string can now be done with a simple macro like this one:
Code:
macro reversed str
        db str bswap (lengthof (str))
end macro    


The BSWAP operator complements the DBX/EMIT directive in that it gives a simple way to define big endian value of length specified by an assembly-time variable. And since it creates the string value, a plain DB directive is then enough to write the result into output:
Code:
dbx length: value bswap length
db value bswap length                   ; same output    
Post 26 Oct 2016, 22:12
View user's profile Send private message Visit poster's website 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.