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>
.
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
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.
.
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
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.
.
See this thread (http://www.masmforum.com/simple/index.php?topic=2013.0).
Quote from: MazeGen on July 17, 2005, 09:18:29 AM
See this thread (http://www.masmforum.com/simple/index.php?topic=2013.0).
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
.
It's a hairbrain scheme I know and probably a waste of time.
heheh.
.
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.
.
Prokster,
That is a good technique you have used in the "CapsMacroText" macro you have published. :U
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.
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?
.
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?
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.
.
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 (http://www.masmforum.com/simple/index.php?topic=2013.0).
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
Quote from: Porkster on July 18, 2005, 02:37:11 PM
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?
Would the EXTERNDEF directive help you? It defines the symbol as external if it's not defined in the module, as public if it is. Is this what you're trying to do?
Cheers,
Randy Hyde
.
Quote
Quote from: Randall Hyde on July 20, 2005, 08:13:16 PM
Would the EXTERNDEF directive help you? It defines the symbol as external if it's not defined in the module, as public if it is. Is this what you're trying to do?
Cheers, Randy Hyde
The 'EXTERNDEF' if a toggle form of using 'PUBLIC'/'EXTERN' so if an external source doesn't define the the variable then it will try to look for the define in the same module of the 'EXTERNDEF' is placed, so it will produce an error if there is none.
Having a command to ignore an error and then the line it's on, if found would the a fix.
.
Quote from: Porkster on July 21, 2005, 10:25:47 AM
Quote from: Randall Hyde on July 20, 2005, 08:13:16 PM
Would the EXTERNDEF directive help you? It defines the symbol as external if it's not defined in the module, as public if it is. Is this what you're trying to do?
Cheers, Randy Hyde
The 'EXTERNDEF' if a toggle form of using 'PUBLIC'/'EXTERN' so if an external source doesn't define the the variable then it will try to look for the define in the same module of the 'EXTERNDEF' is placed, so it will produce an error if there is none.
Having a command to ignore an error and then the line it's on, if found would the a fix.
.
Then would an "ifndef symbol" with a definition in the body of the if work for you?
Cheers,
Randy Hyde