News:

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

Assemble Time Strings. Upper Casing them?

Started by Porkster, July 14, 2005, 04:01:36 PM

Previous topic - Next topic

Porkster

Assemble Time Strings.  Upper Casing them?

I've gone a blank.  I think it did it in the past, but is there a simple way to uppercase an assembly time string?

Example



_String    TEXTEQU   <Hello World>

????  ;; now a command or method to get it to <HELLO WORLD>



.

Mark Jones

Hi Porkster. I like your new avatar. :bg

Here's one way it could be done:


include masm32rt.inc            ; masm32 compile-time libs

.data
    MyString    DB  'Hello World!',0

.code
    mov ecx,offset MyString     ; put pointer in ecx
    dec ecx                     ; decrease one so loop works right
@@:                             ; loop until string is done
    inc ecx                     ; increment pointer
    mov al,byte ptr [ecx]       ; fetch string byte into al
    test al,al                  ; is it a null?
    jz finishit                 ; if so, exit loop
    cmp al,"a"                  ; is byte lower than an ASCII "a"?
    jl @B                       ; if so, skip it
    cmp al,"z"                  ; higher than ASCII "z"?
    jg @B                       ; skip those too
                                ; value here is within range of a-z
    sub al,20h                  ; change ASCII value to a capital
                                ; "A" = 41h, "a" = 61h
    mov byte ptr [ecx],al       ; store altered byte at pointer
    jmp @B                      ; loop until null is found

finishit:
    invoke MessageBox,0,addr MyString,0,MB_OK   ; show our string
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Porkster

Quote from: Mark Jones on July 14, 2005, 05:14:17 PM
Hi Porkster. I like your new avatar. :bg

Thanking you...

QuoteHere's one way it could be done:

Nah, thanks for your effort.   The problem is I'm talking about a assembly level string constant, not a machine code issue.

I've checked all the masm manuals I have and the only way I think I could do it would be to write a (sub) macro to convert the text.  From the features it would be a round about way of indexing a string of "ABCDEF~abcdef~~~~" and doing character testing and transposing the characters that are lower.

.

Vortex

Hi Porkster,

Here is what you need :
Quote
String Directives and Predefined Functions

Directive

SUBSTR

Assigns part of string to a new symbol.

INSTR

Searches for one string within another.

SIZESTR

Determines the size of a string.

CATSTR

Concatenates one or more strings to a single string.

http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_09.htm

Porkster

Quote from: Vortex on July 15, 2005, 10:12:15 AM
Hi Porkster,...

Yep thx.   I was hoping someone would know a hidden command or something.

I will make a macro tonight and maybe share it is others want it.

.


Porkster

#6
Quote from: MazeGen on July 17, 2005, 09:18:29 AM
See this thread.

Thanks.  I made a quick macro but it's still to be REFINED.

The idea is to allow the loading of INC and LIB with a single line but the main aim was to also FLAG a constant that denotes the library is loaded.  The power in that is that it should allow modules or routines to be compiled or not depending on what libraries are loaded.  It's a way around modifing the Lib code themselves do the flagging.

The routine can be refined and also made to do lower case of the macro-text.




; ##### Caps Macro-String, Macro
; ########################################
; Supply Assembly-Time string to be converted to uppercase.

CapsMacroText   MACRO   _String:REQ
LOCAL _PhraseString, _NewString, _Pos, _Char, _WorkSpace
_PhraseString   TEXTEQU   <ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz>
_NewString    TEXTEQU   <>

FORC  _Char, <_String>
_Pos INSTR 1, _PhraseString, <_Char>
IF _Pos GT 26
_WorkSpace SUBSTR _PhraseString, _Pos - 26, 1
_NewString CATSTR _NewString, _WorkSpace
ELSE
_NewString CATSTR _NewString, <_Char>
ENDIF
ENDM
EXITM   <_NewString>
ENDM




; ##### Load Inc & Lib, and Flag a Const
; #################################################################
; Supply the Filename without DotExt to load inc,lib,FLAG_'filename'

mount   MACRO   _File:REQ
LOCAL _WorkSpace
include   &_File&.inc
includelib   &_File&.lib


_WorkSpace    TEXTEQU     CapsMacroText( _File )
_WorkSpace     CATSTR     <PUBLIC FLAG_>, _WorkSpace
_WorkSpace

_WorkSpace     TEXTEQU     CapsMacroText( _File )
_WorkSpace     CATSTR     <FLAG_>, _WorkSpace, < EQU TRUE>
_WorkSpace

ENDM




Then I should be able to


(EXMAPLE)
(In the main assembly)
.const
mount kernel32

(In a module or other situation, it now can
become self tailoring depending on the libraries loaded)
.const
EXTERN     FLAG_KERNEL32:
.code or .whatever...
IFDEF FLAG_KERNEL32
     .....Do routines related to if Kernel32 is loaded...
ENDIF



.

Porkster

It's a hairbrain scheme I know and probably a waste of time.

heheh.

.

Porkster

Consider this idea finished as it's not feasible due to it being easier to manually comment out text and place the inc/lib's where needed.

The main problem I had was testing for the public constant eg: "FLAG_KERNEL32" and then testing it in the module.   The module couldn't see the constant without having a "EXTERN   FLAG_KERNEL32:", but if that constant wasn't loaded the "EXTERN" or "EXTERNDEF" would produce an error.  Taht error seems unavoidable.

The main use of the idea was to write a self building error handling module based on what libraries where loaded.

If anyone knows of a feature to get around the problem then give a yodel.

.

hutch--

Prokster,

That is a good technique you have used in the "CapsMacroText" macro you have published.  :U
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MazeGen

I think it is interesting idea.

I can't see your problem. The following code gets compiled and linked well:


.686
.model flat, stdcall
option casemap :none

; ##### Caps Macro-String, Macro
; ########################################
; Supply Assembly-Time string to be converted to uppercase.

CapsMacroText   MACRO   _String:REQ
LOCAL _PhraseString, _NewString, _Pos, _Char, _WorkSpace
_PhraseString   TEXTEQU   <ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz>
_NewString    TEXTEQU   <>

FORC  _Char, <_String>
_Pos INSTR 1, _PhraseString, <_Char>
IF _Pos GT 26
_WorkSpace SUBSTR _PhraseString, _Pos - 26, 1
_NewString CATSTR _NewString, _WorkSpace
ELSE
_NewString CATSTR _NewString, <_Char>
ENDIF
ENDM
EXITM   <_NewString>
ENDM

; ##### Load Inc & Lib, and Flag a Const
; #################################################################
; Supply the Filename without DotExt to load inc,lib,FLAG_'filename'

mount   MACRO   _File:REQ
LOCAL _WorkSpace
include   \masm32\include\&_File&.inc
includelib   \masm32\lib\&_File&.lib

_WorkSpace     TEXTEQU     CapsMacroText( _File )
_WorkSpace     CATSTR     <FLAG_>, _WorkSpace, < EQU TRUE>
_WorkSpace
ENDM

mount kernel32

.code
start:
IFDEF FLAG_KERNEL32
invoke ExitProcess, 0

ECHO * FLAG_KERNEL32 defined

ELSE
ECHO * FLAG_KERNEL32 not defined
ENDIF

end start


BTW, there's no need for .const directive. It creates run-time read-only data segment, but the mount macro just creates compile-time constant.

Porkster

Quote from: MazeGen on July 18, 2005, 08:14:03 AM...BTW, there's no need for .const directive. It creates run-time read-only data segment, but the mount macro just creates compile-time constant.

Maybe the".Const" like you said is forcing the flag to be scoped as a local-global if there is such a thing.  I have heard before that constants can be related to their defining segments.   So if I put the flag into a module and use .const it may force a unique segment from the main segment.   I will test it out later to see if this is true.

Thanks for the Help Maze.  Also thx Hutch for praise.

UPDATE :

I Did a check and the constant isn't being seen in the module.   To use the "EXTERN" command isn't feasible as it will work if the constant is publicly declared but if it's not then it produces an error which defeates the purpose of the idea/project.  Maybe someone can see something wrong that I'm doing?

.

MazeGen

I don't know whether my poor english is good enough to explain it, but I try it:

The constant (e.g. FLAG_KERNEL32) should not be seen in the module (I assume by "module" you mean some binary form of your code). That's because such constants are resolved and used at compile-time and then they "disappear" - they are no longer needed.

Is I see it, your idea is working, isn't it?

Porkster

Quote from: MazeGen on July 19, 2005, 09:41:14 AM
I don't know whether my poor english is good enough to explain it, but I try it:

The constant (e.g. FLAG_KERNEL32) should not be seen in the module (I assume by "module" you mean some binary form of your code). That's because such constants are resolved and used at compile-time and then they "disappear" - they are no longer needed.

Is I see it, your idea is working, isn't it?

Nope.  The 'FLAG_KERNEL32' constant can't be seen in the module unless I use 'EXTERN FLAG_KERNEL32:'.  The problem with that an error is produced if that command trys on a constant is isn't declared, which makes the idea of variations of loaded libs, unfeasible.

About modules, read in Chapter 8 of the Masm 6.1 manual.

.

Randall Hyde

Quote from: Porkster on July 17, 2005, 09:39:57 AM
Quote from: MazeGen on July 17, 2005, 09:18:29 AM
See this thread.

Thanks.  I made a quick macro but it's still to be REFINED.

The idea is to allow the loading of INC and LIB with a single line but the main aim was to also FLAG a constant that denotes the library is loaded.  The power in that is that it should allow modules or routines to be compiled or not depending on what libraries are loaded.  It's a way around modifing the Lib code themselves do the flagging.

The routine can be refined and also made to do lower case of the macro-text.




; ##### Caps Macro-String, Macro
; ########################################
; Supply Assembly-Time string to be converted to uppercase.

CapsMacroText   MACRO   _String:REQ
LOCAL _PhraseString, _NewString, _Pos, _Char, _WorkSpace
_PhraseString   TEXTEQU   <ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz>
_NewString    TEXTEQU   <>

FORC  _Char, <_String>
_Pos INSTR 1, _PhraseString, <_Char>
IF _Pos GT 26
_WorkSpace SUBSTR _PhraseString, _Pos - 26, 1
_NewString CATSTR _NewString, _WorkSpace
ELSE
_NewString CATSTR _NewString, <_Char>
ENDIF
ENDM
EXITM   <_NewString>
ENDM






Despite MASM's power and capabilities, it's compile-time language facilities are one of the main reasons I wound up abandoning MASM and writing my own assembler. It's so much easier to say something like:

?newstring := @uppercase( oldstring );


However, I congratulate you on your solution. I probably would have used conditional assembly to trap characters in the range 'a'..'z' and done the standard uppercase conversion. Using INSTR was a neat idea.
Cheers,
Randy Hyde