A while back someone posted this code fragment for the "built-in" macro Catstr:
tmp$ CATSTR <chr$("Built on >, @Date, < at >, @Time, <")>
After being assembled tmp$ = chr$("Built on 05/06/22 at at 14:45:47") ;using today
I have 2 question which I hope someone can answer:
1. Is there a "built-in" chr$ function in masm?
1 How is this same code rewritten using @Catstr?
chr$ is a macro. (See macros.asm)
@CatStr( same thing).
include \masm32\include\masm32rt.inc
.code
start:
@CatStr(<print chr$("Built on >, @Date, < at >, @Time, <", 13, 10)>) ; *** fails miserably ***
tmp$ CATSTR <inkey chr$("Built on >, @Date, < at >, @Time, <", 13, 10)>
tmp$
exit
end start
@CatStr() works only in specific settings. Here are a few examples from MasmBasic's Switch_ ... Endsw_ macro:
Switch_ @CatStr(<swMax>, %MbSct, <=-2147483648>)/@CatStr(<swMin>, %MbSct, <=2147483648>
@CatStr(<swMin>, %MbSct, <=2147483648>)/@CatStr(<swArg$>, %MbSct, < equ >, <arg
@CatStr(<swArg$>, %MbSct, < equ >, <arg>)/@CatStr(<swCase>, %MbSct, <=0>)
@CatStr(<swCase>, %MbSct, <=0>)/@CatStr(<jmp swEnd>, %MbSct)
@CatStr(<jmp swEnd>, %MbSct)/ENDM
Case_ curCase=@CatStr(<swCase>, %MbSct)/if curCase
@CatStr(<swCase>, %MbSct, <=swCase>, %MbSct, <+1>) ; inc global case counter/c
@CatStr(<MbSwMin=swMin>, %MbSct)/@CatStr(<MbSwMax=swMax>, %MbSct)
@CatStr(<MbSwMax=swMax>, %MbSct)/FOR cArg, <args>
@CatStr(<MbCase>, %MbSct, <_>, %ctCase, <_>, %curCase, < textequ >, tmp$, <>)/ctCa
@CatStr(<swMin>, %MbSct, <=MbSwMin>)/@CatStr(<swMax>, %MbSct, <=MbSwMax>)
@CatStr(<swMax>, %MbSct, <=MbSwMax>)/@CatStr(<@MbCase>, %MbSct, <_>, %curCase,
@CatStr(<@MbCase>, %MbSct, <_>, %curCase, <:>)/; % echo -------------- cDo: cDo
Default_ @CatStr(<@MbCase>, %MbSct, <_D:>)/ENDM
Endsw_ @CatStr(<@MbCase>, %MbSct, <_D:>)/endif
@CatStr(<swa$ equ !<swArg$>, %MbSct, !>)/@CatStr(<swEnd>, %MbSct, <:>)
@CatStr(<swEnd>, %MbSct, <:>)/if @64
@CatStr(<lea rdx, @MbSwOut>, %MbSct)/push rdx
@CatStr(<push offset @MbSwOut>, %MbSct)/endif
@CatStr(<MbSwMin=swMin>, %MbSct)/@CatStr(<MbSwMax=swMax>, %MbSct)
@CatStr(<MbSwMax=swMax>, %MbSct)/cases=@CatStr(<swCase>, %MbSct)
cases=@CatStr(<swCase>, %MbSct)/curCase=0
ses, < cas>, <es found, >, @signed$(MbSwMin), < .. >, @signed$(MbSwMax), <, uses >,
c$ equ @CatStr(<MbCase>, %MbSct, <_>, %ctCase, <_>, %curCase)/oa INSTR c$, <..>
@CatStr(<jmp @MbCase>, %MbSct, <_D>)/else
@CatStr(<jl @MbCase>, %MbSct, <_D>)/cmp swa$, MbSwMax
@CatStr(<jg @MbCase>, %MbSct, <_D>)/oa = opattr swa$
@CatStr(<lea r9, @MbSwT>, %MbSct, <[-SIZE_P*MbSwMin]>)/lea swa$, [r9+SIZE_P*swa$
@CatStr(<jmp @MbSwT>, %MbSct, <[SIZE_P*swa$-SIZE_P*MbSwMin]>)/endif
@CatStr(<@MbSwT>, %MbSct, <:>)/ctImm=MbSwMin
@CatStr(<jmp @MbCase>, %MbSct, <_D>)/endif
@CatStr(<@MbSwOut>, %MbSct, <:>)/MbSct=MbSct-1
Hi StillLearningMasm,
Here is a quick example :
include \masm32\include\masm32rt.inc
.code
start:
% echo @CatStr(<Built on >, @Date, < at >, @Time)
invoke ExitProcess,0
END start
Some more:
% echo @CatStr(<Built on >, @Date, < at >, @Time)
tmp$ CATSTR <chr$("Built on >, @Date, < at >, @Time, <")>
% echo tmp$
print tmp$
print @CatStr(<"Built on >, @Date, < at >, @Time, <">)
Thanks for all the info and examples.
I came up with a better way:
%tmp equ "Built on &@Date at &@Time"
This eliminates having to use @catstr.
Is there a better way?
Both are ok, it's just a matter of taste :thumbsup:
%tmp equ "Built on &@Date at &@Time"
print tmp
vs
print @CatStr(<"Built on >, @Date, < at >, @Time, <">)
I tried using EQU and TEXTEQU to have your @catstr method save the string being created in the tmp variable name
but could not get it to work. Is there a way to use @catstr and have it save it to a equate variable name like I did?
I finally got my code to work to do this using @catstr but it seems more complicated than what I showed before:
%tmp textequ <@CatStr(<"Built on >, @Date, < at >, @Time, <">)>
If this is the best way to do it then I will use my prior code.
Quote from: StillLearningMasm on May 24, 2022, 12:49:00 PM
I finally got my code to work to do this using @catstr but it seems more complicated than what I showed before:
%tmp textequ <@CatStr(<"Built on >, @Date, < at >, @Time, <">)>
If this is the best way to do it then I will use my prior code.
Perhaps a bit too complicated. Here's what I'd do ( both CatStr and @CatStr ):
echo --------------------------------------------
tmp CatStr <Built on >, @Date, < at >, @Time
%echo tmp
echo --------------------------------------------
tmp textequ @CatStr( <Built on >, @Date, < at >, @Time )
%echo tmp
echo --------------------------------------------
end
Just for curiosity: what's wrong with the shortest and simplest solution?
Quote from: jj2007 on May 24, 2022, 06:22:10 AM
print @CatStr(<"Built on >, @Date, < at >, @Time, <">)
"Cat String" https://youtu.be/atr9l6UpdFY
lol. Video for cats. :biggrin:
Just happened upon that after seeing this thread. Shared here for you amusement.
I still think mine is shorter:
%tmp equ "Built on &@Date at &@Time"
print tmp ;could also be echo tmp
It even assembles faster.
jj2007, I never knew you could have only one double quote between <>.
I didn't see any examples of that in the reference.
Mine is one line, yours is two. So yours is shorter :thumbsup:
Re "assembles faster": Did you time it? How many nanoseconds was it faster?
I did not time it.
I used ollydbg on jwasm and your method took longer to step thru.
Quote from: StillLearningMasm on May 26, 2022, 04:28:23 AM
I used ollydbg on jwasm and your method took longer to step thru.
That sounds very convincing, keep up the good work :thumbsup: