News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Macro behaves differently in test vs real code

Started by jj2007, September 03, 2008, 02:26:55 AM

Previous topic - Next topic

jj2007

This is inspired by MichaelW, see this post.
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

qWord

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
FPU in a trice: SmplMath
It's that simple!

jj2007

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?

qWord

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
FPU in a trice: SmplMath
It's that simple!

jj2007

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 MyBuffer

I 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.

herge

 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.
// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

MichaelW

eschew obfuscation

jj2007

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
...?

hutch--

 :bg

hmmmph,


    outa_here:


Is my standard exit label. :P
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php