News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

txt macro for immediate operands

Started by dsouza123, August 09, 2008, 06:47:48 PM

Previous topic - Next topic

dsouza123

As a result of noob!'s post about using a text string as an immediate operand for dwords
and it being stored in an unobvious order, the reverse of text strings in the .data section,
I wrote a macro txt4 which works for 4 byte strings, but a more flexible version that
works for 2,4,8,16 byte immediate operand strings would be better.


    txt4 MACRO text:VARARG

        nustr equ <>
        slen SIZESTR <text>

     ;; ------------------------------------------------
     ;; test for errors in length
     ;; ------------------------------------------------
        if slen ne 6
          echo ------------------------------------
          echo *** STRING TOO SHORT or TOO LONG ***
          echo ------------------------------------
        .ERR
        EXITM <>
        endif

      ;; ------------------------------------------------
      ;; create a new string in reverse order
      ;; ------------------------------------------------
        nustr1 SUBSTR <text>,1,1
        nustr2 SUBSTR <text>,2,1
        nustr3 SUBSTR <text>,3,1
        nustr4 SUBSTR <text>,4,1
        nustr5 SUBSTR <text>,5,1
        nustr6 SUBSTR <text>,6,1

        nustr  CATSTR nustr6,nustr5,nustr4,nustr3,nustr2,nustr1
        EXITM nustr
    ENDM


A unfinished version of txt, it checks for the string lengths correctly but doesn't do the reverse function.


    txt MACRO text:VARARG

        nustr equ <>
        slen SIZESTR <text>

     ;; ------------------------------------------------
     ;; test for errors in length
     ;; ------------------------------------------------
        if NOT ((slen eq 4) OR (slen eq 6) OR (slen eq 10) OR (slen eq 18))
          echo ------------------------------------
          echo *** STRING TOO SHORT or TOO LONG ***
          echo ------------------------------------
        .ERR
        EXITM <>
        endif

      ;; ------------------------------------------------
      ;; create a new string in reverse order
      ;; ------------------------------------------------
        mustr SUBSTR <text>,1,slen
      % FORC arg, <mustr>
        ENDM

        EXITM nustr
    ENDM


Anyone know how to reverse the string in a flexible way using FORC
or some other way?

jj2007

Quote from: dsouza123 on August 09, 2008, 06:47:48 PM
Anyone know how to reverse the string in a flexible way using FORC
or some other way?

include \masm32\include\masm32rt.inc

txt MACRO arg:REQ
LOCAL tmp$, parseLen, PP
  PP=0
  tmp$ equ <>
  parseLen = @SizeStr(arg)
  WHILE PP lt parseLen
   PP=PP+1
   tmp$ CATSTR @SubStr(arg, PP, 1), tmp$
  ENDM
  % echo tmp$
  EXITM <tmp$>
ENDM

.code
MyText   db "Hello World", 0
AppName   db "Masm32:", 0

start:   
   mov eax, txt("Masm")
   mov edx, offset AppName
   mov edx, [edx]
   .if eax==edx
      invoke MessageBox, 0, chr$("Bingo!"), addr AppName, MB_OK
   .else
      invoke MessageBox, 0, chr$("No success, sooory!"), addr AppName, MB_OK
   .endif
   exit

end start

dsouza123

Thanks jj2007, that works well.
% echo tmp$, that is is a cool trick to see resulting value of the string during assembly.

I was still curious if it could be done using FORC,
using MAZEGEN's $lcase and $ucase macros
for examples on using FORC, this the result.


    txt MACRO text:REQ
        local nustr, letter, char

        slen SIZESTR <text>

     ;; ------------------------------------------------
     ;; test for errors in length
     ;; ------------------------------------------------
        if NOT ((slen eq 4) OR (slen eq 6) OR (slen eq 10) OR (slen eq 18))
          echo ------------------------------------
          echo *** STRING TOO SHORT or TOO LONG ***
          echo ------------------------------------
        .ERR
        EXITM <>
        endif

      ;; ------------------------------------------------
      ;; create a new string in reverse order
      ;; ------------------------------------------------
        nustr equ <>
        FORC letter, <text>
           char TEXTEQU <letter>
           nustr CATSTR char, nustr
        ENDM
        EXITM nustr
    ENDM

jj2007

Quote from: dsouza123 on August 09, 2008, 09:34:50 PM
Thanks jj2007, that works well.
% echo tmp$, that is is a cool trick to see resulting value of the string during assembly.

When developing complex macros, I sometimes add this line:
% echo tmp$
crash
.. to test a specific bit of code.

Quote
I was still curious if it could be done using FORC

Try your luck... for me this excerpt from the Programmer's Guide is pure Chinese. Anyway, SUBSTR works fine. You can slightly shorten it by dropping parselen:

  WHILE PP lt @SizeStr(arg)



FORC Loops

The FORC directive is similar to FOR, but takes a string of text rather than a list of arguments. The statements are assembled once for each character (including spaces) in the string, substituting a different character for the parameter each time through.   

The syntax looks like this:

FORC parameter, < text>
statements
ENDM

The text must be enclosed in angle brackets. The following example illustrates FORC:

FORC arg, <ABCDEFGHIJKLMNOPQRSTUVWXYZ>
    BYTE  '&arg'             ;; Allocate uppercase letter
    BYTE  '&arg' + 20h       ;; Allocate lowercase letter
    BYTE  '&arg' - 40h       ;; Allocate ordinal of letter
ENDM

Notice that the substitution operator must be used inside the quotation marks to make sure that arg is expanded to a character rather than treated as a literal string.

With versions of MASM earlier than 6.0, FORC is often used for complex parsing tasks. A long sentence can be examined character by character. Each character is then either thrown away or pasted onto a token string, depending on whether it is a separator character. The new predefined macro functions and string processing directives discussed in the following section are usually more efficient for these tasks.


jj2007

Quote from: jj2007 on August 09, 2008, 11:03:17 PM
Quote from: dsouza123 on August 09, 2008, 09:34:50 PM
I was still curious if it could be done using FORC

Try your luck... for me this excerpt from the Programmer's Guide is pure Chinese

I learnt Chinese :toothy

txt MACRO arg:REQ
LOCAL tmp$
  tmp$ equ <>
  FORC char, <arg>
   tmp$ CATSTR <char>, tmp$
  ENDM
  EXITM <tmp$>
ENDM