This is inspired by MichaelW, see this post (http://www.masm32.com/board/index.php?topic=8602.msg62640#msg62640).
First, the simple part:
CrtString MACRO var, BufLen
LOCAL lbl
.data?
align 4
lbl label byte
ORG $+BufLen-1
db ?
.data
var dd lbl ;; define it in the data section
.code
ENDM
This is a great little helper - just call it as CrtString File$, MAX_PATH (without declaring File$ earlier!).
Now I wanted to be clever and got banged over the head: I included the possibility to use a register as the first argument:
CreateBuffer edi, BufSize
It works perfectly, so it seems:
+Path$+
ir1=0
ir2=0
ACTION: Path$ dd ??0019
+EBX+
ir1=0
ir2=21
ACTION: mov EBX, offset ??001E
+edi+
ir1=17
ir1=17
ACTION: mov edi, offset ??0022
But disable .err and run it through Olly to discover that ML.EXE does something different from what the echos suggest...
include \masm32\include\masm32rt.inc
CreateBuffer MACRO var, BufLen
LOCAL lbl, IsReg, tmp$, x$
echo
tmp$ CATSTR <+>,<var>,<+>
% echo tmp$
% IsReg INSTR <+eax+ecx+edx+esi+edi+ebx+>, <tmp$>
x$ CATSTR <ir1=>, %IsReg
% echo x$
if IsReg eq 0
% IsReg INSTR <+EAX+ECX+EDX+ESI+EDI+EBX+>, <tmp$>
x$ CATSTR <ir2=>, %IsReg
endif
% echo x$
.data?
align 4
lbl label byte
ORG $+BufLen-1
db ?
% if IsReg
echo ACTION: mov var, offset lbl
mov var, offset lbl ;; pass a pointer to the register
else
.data
echo ACTION: var dd lbl
var dd lbl ;; define it in the data section
endif
.code
ENDM
.data?
dx1 dd ?
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
BufSize equ 10000000 ; 100 MB: 200 ms extra, 1 GB: 50 seconds
; int 3 ; breakpoint for Olly
mov dx1, 11111111h ; for debugging - see where the pointer to Path$ is being put
nop
CreateBuffer Path$, BufSize
nop
CreateBuffer EBX, BufSize
nop
CreateBuffer edi, BufSize
nop
echo
; .err ; <--- comment out to run the code
mov ebx, edi
sub ebx, Path$
MsgBox 0, str$(ebx), "CreateBuffer test:", MB_OK
xor ebx, ebx
.While ebx < BufSize
mov BYTE PTR[edi+ebx], 255
movzx eax, BYTE PTR[edi+ebx]
.IF eax != 255
print "oops",13,10
.ENDIF
inc ebx
.Endw
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
hi,
because I'm hating local macro variables, I've just rewritten your macro. it seems like it works propper :bg
CreateBuffer macro var,BufLen
IFNDEF CrBu_lbl_cntr
CrBu_lbl_cntr = 0
ELSE
CrBu_lbl_cntr = CrBu_lbl_cntr + 1
ENDIF
CrBu_str TEXTEQU <CrBu_buffer_>,%CrBu_lbl_cntr
CrBu_num = 0
FOR reg,<eax,ecx,edx,esi,edi,ebx>
IFIDNI <reg>,<var>
CrBu_num = 1
EXITM
ENDIF
ENDM
.data?
align 4
;CrBu_str db BufLen dup(?)
CrBu_str label byte
ORG $+BufLen-1
db ?
.code
IF CrBu_num NE 0
mov var,OFFSET CrBu_str
ELSE
.data
align 4
var dd OFFSET CrBu_str
.code
ENDIF
endm
EDIT:
I've just found your failure: you've forgot do change to code-segment before "mov var,.."
CreateBuffer MACRO var, BufLen
LOCAL lbl, IsReg, tmp$, x$
echo
tmp$ CATSTR <+>,<var>,<+>
% echo tmp$
% IsReg INSTR <+eax+ecx+edx+esi+edi+ebx+>, <tmp$>
x$ CATSTR <ir1=>, %IsReg
% echo x$
if IsReg eq 0
% IsReg INSTR <+EAX+ECX+EDX+ESI+EDI+EBX+>, <tmp$>
x$ CATSTR <ir2=>, %IsReg
endif
% echo x$
.data?
align 4
lbl label byte
ORG $+BufLen-1
db ?
% if IsReg
echo ACTION: mov var, offset lbl
.code
mov var, offset lbl ;; pass a pointer to the register
else
.data
echo ACTION: var dd lbl
var dd lbl ;; define it in the data section
.code
endif
ENDM
regards
qWord
Quote from: qWord on September 03, 2008, 11:42:39 AM
I've just found your failure: you've forgot do change to code-segment before "mov var,.."[/b]
regards
qWord
You are genius, thanks a lot :U
What's wrong with local mac vars, by the way?
Quote from: jj2007 on September 04, 2008, 08:46:35 AM
What's wrong with local mac vars, by the way?
-> 1. there are only ~65536~ local variables available - I've just reached this limed some years ago while writing a huge macro-system :'(
2. i can't remember exactly why i "hate" them, but it goes back to time when I started writing macros. Eventually it was triggered by frustration or some thing like that :bg
Quote from: qWord on September 04, 2008, 10:04:26 AM
-> 1. there are only ~65536~ local variables available - I've just reached this limed some years ago while writing a huge macro-system :'(
Wow, sounds impressing! I'll keep that in mind.
For those who write smaller proggies, here the final version:
crtbuf MACRO var, BufLen
LOCAL lbl, IsReg
IsReg INSTR <+eax+ecx+edx+esi+edi+ebx+>, @CatStr(<+>,<var>,<+>)
if IsReg eq 0
IsReg INSTR <+EAX+ECX+EDX+ESI+EDI+EBX+>, @CatStr(<+>,<var>,<+>)
endif
.data?
align 4
lbl LABEL byte
ORG $+BufLen-1
db ?
if IsReg
.code
mov var, offset lbl ;; pass a pointer to the register
else
.data
var dd lbl ;; define it in the data section
.code
endif
ENDM
Usage (remember these variables must not have been declared before!):
.code
start:
crtbuf Path$, MAX_PATH
crtbuf IniFile$, MAX_PATH
crtbuf FatBuffer, 1000000
crtbuf edi, 1000
crtbuf EDI, 1000000
The
crtbuf Path$, MAX_PATH is somewhat shorter than MichaelW's original macro, because it uses the equivalent of
.data?
MyBuffer db MAX_PATH dup (?)
.data
Path$ dd Mybuffer
instead of a
mov Path$, offset MyBufferI have tested it with 6*100 MB under Windows XP, no problem, except when loading it into OllyDbg you get a message that Olly cannot allocate so much memory.
Hi jj2007:
You only need inkey
instead of
inkey "Press any key to exit..."
Press any key to exit...
is the dafault for inkey macro.
Regards herge.
The default is "Press any key to continue ..."
Quote from: MichaelW on September 06, 2008, 11:10:09 AM
The default is "Press any key to continue ..."
Please change to
inkey "Hit any key to get outta here quickly" :wink
Since we are back into philosophical debates: Any suggestions for a better name?
crtbuf Path$, MAX_PATH
createbuffer Path$, MAX_PATH
mkbuf Path$, MAX_PATH
mkstr Path$, MAX_PATH
...?
:bg
hmmmph,
outa_here:
Is my standard exit label. :P