do i need to be worried about reg preservation when using the switch macro ?
i mean will it destroy any registers ?
don't really know anything about macros.
also...
could i do
switch eax
case 1
;code
ret
etc..
endsw
i think in the other loop macros .while, .repeat .break, .continue & .if none of the registers are affected.. could you confirm this ?
and for the macros in the high level help file, is there any listing somewhere as to which macros use which registers ? - so that they can be preserved accross their usage.
eax is not preserved, the others are.
In case of doubt, go to D:\masm32\macros\macros.asm and look for switch macro _var:req, _reg:=<eax>
Fascinating lecture ;-)
Another option:
mov eax, 1001
mov ecx, 1002
mov edx, 1003
Switch ecx
case 1001
case 1002
...
check old values of eax, ecx, edx
(but be aware that print, MessageBox, str$ etc destroy these registers)
jj wrote..
Quote(but be aware that print, MessageBox, str$ etc destroy these registers)
yes, was just asking about the switch macro itself
so i need to just preserve
eax accross a switch statement
thx
Rainstorm,
There is no problem using EAX with thw switch macro and it will test the values in each section without changing the value BUT if it matches a value and the code in that section writes to EAX, then EAX will be changed. The "switch" macro uses the .IF block notation below it which in turn uses comparisons to either a register, immediate or memory operands.
The end result is EAX is safe for the comparisons but may be changed by the code in a block AFTER a comparison. If you need the value that is in EAX to be preserved, do that BEFORE the switch block and restore it after.
hutch,
that's exactly what i wanted to know..Thanks so much for clearing that up :thumbu
-
Quote from: hutch-- on August 31, 2008, 02:23:23 PMit will test the values in each section without changing the value BUT if it matches a value and the code in that section writes to EAX, then EAX will be changed.
switch macro _var:req, _reg:=<eax>
mov _reg, _var
Example:
switch _lParam ->
mov eax, lParam
EDIT:
The switch/case/endsw structure itself modifies
only eax. So you
can use it inside a loop that relies on ecx and edx.
Variant: SWITCH lParam, ecx ; uses ecx but leaves eax intact
RainStorm,
Remember that EAX is a General Purpose register and that nothing should ever be left in it that might be needed. In general, all APIs will return a value in EAX (even zero is a value) so if there are any invoke statements in your switch block, say goodbye to the value you needed.
-- Paul
Paul, I'll keep that in my mind.... thx :thumbu
I didn't try to generate a list, but a quick search through the current macros.asm shows that most of the macros alter EAX, many alter ECX, none alter EDX directly (but any that use call or invoke may alter EDX), none alter EBX, and a small number alter ESI and/or EDI. In practice, I have encountered few problems with this, but as a rule I don't depend on EAX, ECX, or EDX being preserved.
Michael wrote..
Quoteand a small number alter ESI and/or EDI.
if they do.. they back them up before altering them, don't they ? (esi & edi ..that is)
it kinda feels different.. saving the regs for macros than the usual procedures with invoke etc..
maybe that's because of the flow & style,they are in... & the ability to nest them.
like many in the hlhelp are in the form like;.....
mov variable, uval(pstring)
so while coding.. makes you feel like all the registers were backed up, or wish at least,.. & that you don't need to backup any of the 6, not just the volatile ones
: )many thanks.
:: MIchael for your timing macros.. i don't need to back up any.. right?
Only about half of the macros that use ESI and/or EDI preserve them. ShellAboutBox and Mcopy alter both, lob alters ESI, and stb alters EDI. For Mcopy, lob, and stb, I think the registers are not preserved as a speed optimization.
The first version of my timing macros (timers.asm) alter EAX, EBX, ECX, and EDX. The alteration of EBX is a side effect of using CPUID to serialize instruction execution, and I could find no good way to avoid it without compromising the serialization effect. In the second set of macros (counter2.asm) I preserved EBX around CPUID, and just accepted that this would compromise the serialization effect.
Quote from: MichaelW on September 01, 2008, 08:39:05 AM
Only about half of the macros that use ESI and/or EDI preserve them. ShellAboutBox and Mcopy alter both, lob alters ESI, and stb alters EDI. For Mcopy, lob, and stb, I think the registers are not preserved as a speed optimization.
For Mcopy, lob, and stb, a little warning might be ok. LastErr$ has a pushad, so that's fine. But ShellAboutBox should be changed, there is no compelling reason to trash these registers.
The two macros "lob" and "stb" are replacements for LODSB and STOSB and in both cases (with or without the string instructions) the registers should be preserved. The same for Mcopy, as they are macros and not procedures, it is appropriate to do the register preservations at the procedural level, not at the macro level.
The ShellAboutBox macro needs to be fixed, that will be done shortly.
This is the form I will put in the macros file.
ShellAboutBox MACRO handle,IconHandle,quoted_Text_1,quoted_Text_2:VARARG
LOCAL AboutTitle,AboutMsg,buffer,lbl0
.data?
buffer db 128 dup (?)
.data
align 4
AboutTitle db quoted_Text_1,0
AboutMsg db quoted_Text_2,0
align 4
.code
or ecx, -1
lbl0:
add ecx, 1
mov al, [AboutTitle+ecx]
mov [buffer+ecx], al
cmp ecx, LENGTHOF AboutTitle
jl lbl0
invoke ShellAbout,handle,ADDR buffer,ADDR AboutMsg,IconHandle
ENDM