Hey guys,
Got another question for you.
I know how to define variables locally like this: LOCAL variable:DWORD however there's another type of variable that I would like to define locally.
Normally under .data I might declare a variable as follows: atoi db "atoi",0 where the variable atoi points to the string "atoi"
My question to you guys is whether I can declare the variable atoi the same way but so that it can only be accessed locally in the function where it is defined?
Thanks,
-Sean
Sean,
A LOCAL variable is allocated on the stack at runtime so it works differently. With a local like,
LOCAL MyVar :DWORD
LOCAL pvar :DWORD
It will end up a memory address something like [esp-8] and to access its address you need to do the following.
lea eax, MyVar ; get the actualy address of the local stack variable.
mov pvar, eax
If you just need to put a value in the local variable this will work.
mov MyVar, 1234
this is not good code,but anyway does the job :bg
MyProc proc
local szHello[50]:byte
;put some string
lea eax,szHello
mov byte ptr [eax],'H'
mov byte ptr [eax+1],'E'
mov byte ptr [eax+2],'L'
mov byte ptr [eax+3],'L'
mov byte ptr [eax+4],'O'
mov byte ptr [eax+5],0 ;NULL terminated string
;do whatever you want :green
.
.
.
ret
MyProc endp
as i said before,this is a bad job, i am asking here if some one have a macro to do this ?
thank you .
is there a macro to do the above work like this:
this is not good code,but anyway does the job :bg
MyProc proc
local szHello[50]:byte
;put some string
MyMacro szBuffer,"HELLO"
;do whatever you want :green
.
.
.
ret
MyProc endp
where the MyMacro macro does not declare any variable in the .data section (or .data? , or ...)
es,
The masm32 "sas" macro. It puts data in the data section like normal then assigns a local variable as a pointer to it.
Quote from: hutch-- on January 13, 2008, 11:37:48 AM
es,
The masm32 "sas" macro. It puts data in the data section like normal then assigns a local variable as a pointer to it.
yes,
but is there a way to write a macro that does not put data in the data section?
The problem is you must first allocate the room on the stack to do it.
LOCAL myBytes[64]:BYTE ; allocate 64 bytes
Then write immediate data to that memory location range.
mov [ebp-64], "4321"
mov [ebp+60], "8765" etc ....
This is basically how its done.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
call main
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
LOCAL bytes[64]:BYTE
mov DWORD PTR [ebp-64], "4321"
mov DWORD PTR [ebp-60], "8765"
mov WORD PTR [ebp-56], "09"
mov BYTE PTR [ebp-54], 0
invoke MessageBox,0,ADDR bytes,ADDR bytes,MB_OK
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
is it possible to write a macro to do that, i mean like this:
main proc
LOCAL bytes[64]:BYTE
MyMacro bytes,"12345467890"
invoke MessageBox,0,ADDR bytes,ADDR bytes,MB_OK
ret
main endp
where in the macro named MyMacro, we loop through "1234567890" using the pre-processor of masm .
You mean something like this...?
.686
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
strcpy macro var:req,str:req
local i,l,c1,c2,c3,c4,t
i = 2
l sizestr <str>
repeat (l - 2) / 4
c1 substr <str>,i+3,1
c2 substr <str>,i+2,1
c3 substr <str>,i+1,1
c4 substr <str>,i,1
t catstr <">,c1,c2,c3,c4,<">
mov dword ptr var[i-2],t
i = i + 4
endm
if i lt l
t catstr <">
while i lt l
l = l - 1
c1 substr <str>,l,1
t catstr t,c1
endm
t catstr t,<">
mov dword ptr var[i-2],t
else
mov byte ptr var[i-2],0
endif
endm
.code
greet proc
local text[64]:byte
local caption[64]:byte
strcpy text,"Hello, dear. How are you?"
strcpy caption,"strcpy macro"
invoke MessageBox,0,addr text,addr caption,0
ret
greet endp
start:
invoke greet
invoke ExitProcess,0
ret
end start
Looks like a bit of an overkill. Try this:
include \masm32\include\masm32rt.inc
.code
start: call HelloDear
exit
HelloDear proc
LOCAL MyTitle[128]:BYTE
LOCAL pMyTitle:DWORD
LOCAL MyText[128]:BYTE
LOCAL pMyText:DWORD
lea eax, MyTitle
mov pMyTitle, eax
lea eax, MyText
mov pMyText, eax
invoke szCopy, chr$("Just a test:"), pMyTitle
invoke szCopy, chr$("Hello dear, how's life today?"), pMyText
invoke MessageBox, 0, pMyText, pMyTitle, MB_OK
ret
HelloDear endp
end start
Quote from: jj2007 on January 14, 2008, 09:40:39 PM
Looks like a bit of an overkill.
Oops! I should read questions more carefully; chr$ does of course use the .data section, sorry :green
Quote from: xmetal on January 14, 2008, 07:25:39 PM
You mean something like this...?
.686
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
strcpy macro var:req,str:req
local i,l,c1,c2,c3,c4,t
i = 2
l sizestr <str>
repeat (l - 2) / 4
c1 substr <str>,i+3,1
c2 substr <str>,i+2,1
c3 substr <str>,i+1,1
c4 substr <str>,i,1
t catstr <">,c1,c2,c3,c4,<">
mov dword ptr var[i-2],t
i = i + 4
endm
if i lt l
t catstr <">
while i lt l
l = l - 1
c1 substr <str>,l,1
t catstr t,c1
endm
t catstr t,<">
mov dword ptr var[i-2],t
else
mov byte ptr var[i-2],0
endif
endm
.code
greet proc
local text[64]:byte
local caption[64]:byte
strcpy text,"Hello, dear. How are you?"
strcpy caption,"strcpy macro"
invoke MessageBox,0,addr text,addr caption,0
ret
greet endp
start:
invoke greet
invoke ExitProcess,0
ret
end start
EDIT: This works great, thanks for all the help guys :D
-Sean
thank you xmetal , it works,this is what i wanted.
thank you.