Hi,
I'm struggling to create a macro which duplicates instructions:
what I want to achieve is instead of writing this:
mov ymm1, [rax + 32*0]
mov ymm2, [rax + 32*1]
mov ymm3, [rax + 32*2]
I want to write like this:
DUPINSTR <mov ymm&i, [rax + 32*(&i+1)]>
How do I create such a macro ?
Thanks
Like this, for example (with xmm because my CPU doesn't know about ymm):
include \masm32\include\masm32rt.inc
.686
.xmm
DUPINSTR MACRO diLine, range
LOCAL isdots, iseq, is, ctStart, ctEnd, ct, tmp$, di$, diR$
iseq INSTR <range>, <=>
isdots INSTR <range>, <..>
tmp$ SUBSTR <range>, iseq+1, isdots-iseq-1
ctEnd SUBSTR <range>, isdots+2
ct=ctEnd-tmp$
ctStart=tmp$
REPEAT ct
di$ CATSTR <diLine>, < >
is INSTR <diLine>, <&i>
While is
diR$ SUBSTR di$, is+2
diL$ SUBSTR di$, 1, is-1
di$ CATSTR diL$, %ctStart, diR$
is INSTR di$, <&>
ENDM
% echo ## di$
di$
ctStart=ctStart+1
ENDM
ENDM
.code
TestArray dq 100h, 200h, 300h, 400h, 500h, 600h, 700h, 800h, 900h, 1000h
start:
mov eax, offset TestArray
int 3 ; for Olly
; DUPINSTR <mov ymm&i, [rax + 32*(&i+1)]>
DUPINSTR <movlps xmm&i, qword ptr [eax + 32*(&i+1)]>, i=0..3
exit
end start
<ModuleEntryPoint> Ú$ B8 00104000 mov eax, 00401000
00401055 ³. CC int3
00401056 ³. 0F1240 20 movlps xmm0, [eax+20]
0040105A ³. 0F1248 40 movlps xmm1, [eax+40]
0040105E ³. 0F1250 60 movlps xmm2, [eax+60]
00401062 ³. 6A 00 push 0 ; ÚExitCode = 0
00401064 À. E8 01000000 call <jmp.&kernel32.ExitProcess> ; ÀKERNEL32.ExitProcess
Thank you very much, that works.
However, to make it more generic , do you think it is possible to support subscripts like this xmm&i+1 ? Or maybe written like this : xmm&%i+1 ? Just some way to get computed register index.
Another question- why doesn't this code work:
expand macro text,i
text
endm
...
expand <mov xmm&i,xmm&i>, 2
Thanks.
Works with ML 6.14 and 6.15 but not with higher ML versions or JWasm:
DUPINSTR <movlps xmm(&i+1), qword ptr [eax + 32*(&i+1)]>, i=0..3
Re expand: Why should it work?
QuoteWorks with ML 6.14 and 6.15 but not with higher ML versions or JWasm
No way to make it work with ML 12 ?
QuoteWhy should it work?
Because '&' is a text substitution operator and there is a variable 'i' inside macro 'expand' ?
Thanks.
Quote from: sergeyn on April 15, 2014, 09:24:03 AMBecause '&' is a text substitution operator and there is a variable 'i' inside macro 'expand' ?
As you said right, it does substitute text: search string x an replace it with text y. A simple solution that might not look that intuitive is:
e macro expr
EXITM %expr
endm
DUPINSTR macro iStart:=<0>,iEnd:req,iIncr:=<1>,txt:=<>
tmpMacro macro i
% txt
endm
dupi_cntr = iStart
WHILE dupi_cntr LE iEnd
tmpMacro %dupi_cntr
dupi_cntr = dupi_cntr + iIncr
ENDM
endm
;...
DUPINSTR 0,6,1,<movaps xmm&e(&i+1), OWORD ptr [eax + 32*&i]>
If evaluation is needed, use "&e(expression)". Remarks that the angle brackets <> are needed.
(you might change the macro name "e"...)
Thank you so much!
You saved my day!
Addendum: the exclamation mark is not needed: "&e(&i+1) also works.
Burning the midnight oil, he?
:t
Hi Again
Exactly the last version you've posted gives me an error
error A2006: undefined symbol : dupi_cntr
any clue ?
Thanks.
Edit:
This works for me:
expand macro iStart:req,iEnd:req,txt:req
local ii
ii = iStart
WHILE ii LE iEnd
for i,<%ii>
% txt
endm
ii = ii + 1
ENDM
endm
I really want to understand how preprocessor works. If you have a clue, please enlighten me why this doesn't work:
expand macro iStart:req,iEnd:req,txt:req
local i
i = iStart
WHILE i LE iEnd
% txt
i = i + 1
ENDM
endm
and this doesn't work either:
expand macro i:req,iEnd:req,txt:req
WHILE i LE iEnd
% txt
i = i + 1
ENDM
endm
Thanks again!
Quote from: sergeyn on April 17, 2014, 12:51:42 AMExactly the last version you've posted gives me an error
error A2006: undefined symbol : dupi_cntr
any clue ?
probably you used nonnumeric input for first macro parameter thus dupi_cntr is never assigned/created.
Quote from: sergeyn on April 17, 2014, 12:51:42 AMwhy this doesn't work:
expand macro iStart:req,iEnd:req,txt:req
local i
i = iStart
WHILE i LE iEnd
% txt
i = i + 1
ENDM
endm
the expansion operator as first char. in line only substitute text macros -
i is not a text macro.
Quote from: sergeyn on April 17, 2014, 12:51:42 AM
expand macro i:req,iEnd:req,txt:req
WHILE i LE iEnd
% txt
i = i + 1
ENDM
endm
macro parameters are no variables - they will be substitute (text replacement) before evaluating the macro.
For more details see the MASM programmers guide chapter 9.
QuoteFor more details see the MASM programmers guide chapter 9.
Could you share the link ?
Quote from: sergeyn on April 17, 2014, 01:54:00 AMCould you share the link ?
search engine broken? ;)
MASM_6.1_Manuals_[High_Quality_PDF].zip
EDIT: link removed.
Thanks. Just wanted to have the exact version you are referring to. I've read a bunch of them and all are not providing too deep details about differences in numeric and textual variables and their use.
Quote from: qWord on April 17, 2014, 02:02:29 AM
MASM_6.1_Manuals_[High_Quality_PDF].zip (http://www.4shared.com/zip/lCNJTTZk/MASM_61_Manuals_High_Quality_P.html)
Once you have bypassed all the ads, you may succeed in downloading MASM_6.1_Manuals_[High_Quality_PDF].exe
According to Eset (http://virusscan.jotti.org/en-gb/scanresult/ded3809da932b1bafa37255199eeb7ce60a9ea3a), it contains Win32/4Shared.R, a trojan.
PeView reveals that the exe has lots of imports from WinHTTP.dll, such as WinHttpReadData etc...
The limit for attachments is 512 k ;-)
Quote from: jj2007 on April 17, 2014, 03:04:09 AM
Once you have bypassed all the ads, you may succeed in downloading MASM_6.1_Manuals_[High_Quality_PDF].exe
According to Eset (http://virusscan.jotti.org/en-gb/scanresult/ded3809da932b1bafa37255199eeb7ce60a9ea3a), it contains Win32/4Shared.R, a trojan.
PeView reveals that the exe has lots of imports from WinHTTP.dll, such as WinHttpReadData etc...
The limit for attachments is 512 k ;-)
yep, just copied that link from the old board... :icon_confused:
Funny situation ;)
Is this what you mean ?
http://people.sju.edu/~ggrevera/arch/references/MASM61PROGUIDE.pdf (http://people.sju.edu/~ggrevera/arch/references/MASM61PROGUIDE.pdf)
Quote from: sergeyn on April 17, 2014, 04:05:09 AMIs this what you mean ?
http://people.sju.edu/~ggrevera/arch/references/MASM61PROGUIDE.pdf (http://people.sju.edu/~ggrevera/arch/references/MASM61PROGUIDE.pdf)
no.
I've temporarily uploaded it here: MASM_6.1_Manuals_High_Quality_PDF.zip (http://remixshare.com/download/w3mwr).
Looks more trustworthy indeed :t
QuoteLEA Load Effective Address
Calculates the effective address (offset) of the source memory operand and stores the result in the destination register. If the source operand is a direct memory address, the assembler encodes the instruction in the more efficient MOV reg,immediate form (equivalent to MOV reg, OFFSET mem).
Hmmm... my assemblers don't do that :(
QuoteA Word About Instruction Timings
...
• Smaller is often better. For example, the instructions
dec bx
sub bx, 1
accomplish the same thing and have the same timings on 80386/486 processors.
But the first instruction is 3 bytes smaller than the second, and so may reach the
processor faster.
• When possible, use the string instructions described in Chapter 5, "Defining and
Using Complex Data Types."
:greensml:
Hi qWord,
Quote from: qWord on April 17, 2014, 04:36:58 AM
I've temporarily uploaded it here: MASM_6.1_Manuals_High_Quality_PDF.zip (http://remixshare.com/download/w3mwr).
thank you for sharing the files. :t
Gunther
the masm assembler does make a few substitutions for you :P
xchg edx,eax ;2 bytes
xchg eax,edx ;1 byte
Coming back to the topic, I just thought the macro could be generalized with a few modifications:
e macro expr
EXITM %expr
endm
FOR_ macro start:=<i=0>,condition:req,increment:=<i=i+1>,statement:=<>
% tmpMacro1 macro @SubStr(<&start>,1,@InStr(1,<&start>,<=>)-1)
% statement
endm
tmpMacro2 macro varName
LOCAL varName
start
WHILE condition
tmpMacro1 %varName
increment
ENDM
endm
% tmpMacro2 @SubStr(<&start>,1,@InStr(1,<&start>,<=>)-1)
endm
-->
FOR_ k=0,k LT 7,k=k+1,<movdqa xmm&k,OWORD ptr [eax+k*OWORD]>
The variable name is freely selectable.
With some more lines and if one like that syntax:
FOR_ macro start:=<i=0>,condition:req,increment:=<i=i+1>,statements:=<>
for_vars TEXTEQU <>
for_expvars TEXTEQU <>
FOR arg,<&start>
for_vars TEXTEQU for_vars,<,>,@SubStr(<&arg>,1,@InStr(1,<&arg>,<=>)-1)
for_expvars TEXTEQU for_expvars,<,!%>,@SubStr(<&arg>,1,@InStr(1,<&arg>,<=>)-1)
ENDM
for_vars SUBSTR for_vars,2
for_expvars SUBSTR for_expvars,2
% tmpMacro1 macro &for_vars
FOR statement,<&statements>
% statement
ENDM
endm
tmpMacro2 macro varNames:VARARG
LOCAL varNames
FOR arg,<&start>
arg
ENDM
WHILE condition
% tmpMacro1 &for_expvars
FOR arg,<&increment>
arg
ENDM
ENDM
endm
% tmpMacro2 &for_vars
endm
-->
FOR_ i=0,i LT 7,i=i+1,\
<<movdqa xmm&e(i+1),OWORD ptr [eax+i*OWORD]>>
;...
FOR_ <i=0,j=7>,i LT 4,<i=i+1,j=j-1>,\
<\
<mov al,sz[i]>,\
<mov ah,sz[j]>,\
<mov sz[i],ah>,\
<mov sz[j],al>,\
>
:biggrin:
Hello again,
Sorry for noobie questions - trying to extend the expand macro to support multi-line generation, and stuck with a very simple thing.
For debugging purposes trying to print the value of a variable:
work MACRO args:VARARG
work MACRO
local ii
ii = 999
ECHO !ii is: %ii
ENDM
work
I get this printed:
!ii is: ??0000
What am I doing wrong?
work MACRO args:VARARG
local ii, tmp$
ii = 999
tmp$ CATSTR <!ii is: >, %ii, < with !args=>, <args>
% echo tmp$
ENDM
Ok, so my mistake was that everything after 'echo' is simply dumped to the screen without any substitutions.
How do you guys debug macros ? Is there a way to generate preprocessed file similar to what /P flag of cl.exe does? The closest I found to see what's going on inside is "/Sa Maximize source listing". I basically want to see what the evaluator gets on it's input.
Another issue I've discovered - VARARG parameters can't properly parse commas, thus a two argument call like <1,2>,<2,3> is seen as <1>,<2>,<3>,<4> by the vararg parsing code (as described in the docs). Do you know anyway to work around that ?
Thank you for you help!
Quote from: sergeyn on April 18, 2014, 08:52:21 PMHow do you guys debug macros ?
With tmp$ CATSTR and .err as shown below.
QuoteAnother issue I've discovered - VARARG parameters can't properly parse commas, thus a two argument call like <1,2>,<2,3> is seen as <1>,<2>,<3>,<4> by the vararg parsing code (as described in the docs). Do you know anyway to work around that ?
Masm separates arguments by commas, but you are not forced to use commas.
include \masm32\include\masm32rt.inc
xx MACRO args:VARARG
LOCAL tmp$
tmp$ CATSTR <Myargs=>, <args>
% echo tmp$
for arg, <args>
echo arg
endm
ENDM
.code
start:
xx <1,2>, <2,3>
xx <1:2>, <2:3>
.err
end start
Echos:
Myargs=1,2,2,3
1
2
2
3
Myargs=1:2,2:3
1:2
2:3