flat assembler
Message board for the users of flat assembler.

Index > Windows > Procedures (string arguments, arguments addressing)

Author
Thread Post new topic Reply to topic
jumpex



Joined: 29 Jan 2006
Posts: 38
jumpex 18 Jun 2007, 17:16
Good day. (:
I have a couple of questions about PROCedures. I want to define a procedure that takes two arguments. Here it is:

proc xer,subst:WORD,repla:WORD
;blablabla
ret
endp

The two arguments are:

nopatch db "blablabla2",0
patch db "blablabla1",0

I'm calling the procedure like this:

invoke xer,nopatch,patch

What am I doing wrong? And why it's not working.
Another question - how can I address the second last argument in the stack. I've read that the first is [ebp+8]. Why am I not grasping the concept of this? Just... can somebody explain it to me clearer?
Post 18 Jun 2007, 17:16
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 18 Jun 2007, 17:42
Here is the documentation about Win32 Headers http://flatassembler.net/docs.php?article=win32 (includes proc explanation).

Your problem is that you must use stdcall instead. With invoke the first parameter is the address of a pointer to proc while with stdcall, the first parameter is the address of the proc.

Code:
; invoke xer, nopatch, patch
  push patch
  push nopatch
  call dword [xer]


; stdcall xer, nopatch, patch
  push patch
  push nopatch
  call xer    


Above is the difference between using invoke and stdcall for your particular procedure.

About addressing parameters it is explaned in the documentation
Post 18 Jun 2007, 17:42
View user's profile Send private message Reply with quote
jumpex



Joined: 29 Jan 2006
Posts: 38
jumpex 20 Jun 2007, 13:31
Thank you for your responce. Is there a way to use the 'invoke' method? Also I have another problem.

Procedure:

Code:
proc xer,repla:WORD,subst:WORD

locals
key db "SOFTWARE\Skype\Phone",0
value db "SkypePath",0
path dd 256 dup(?),0
skyhand dd ?
endl

invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,key,0,KEY_READ,skyhand

endp    


Error:

Quote:
Invalid value. (pushd ...var?000068F)


On line with the RegOpenKeyEx function. When I declare the variables outside the procedure in the program, where I'm calling it, all works fine. What is the problem with the local variable? (key or skyhand are the problem, I guess)
Post 20 Jun 2007, 13:31
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Jun 2007, 15:27
You don't really read the documentation, don't you? Wink

The problem is that you are referencing variables in stack space which has no absolute offset but EBP-relative offset. To pass the offset of such variables you have to use "addr var" (again read documentation).

BTW, note that initializing vars in locals generates code that loads them in run-time everytime you call the procedure. I suggest this code
Code:
proc xer,repla:WORD,subst:WORD 
locals 
path dd 256 dup(?),0 ; do you really need the ending zero and 1024 bytes for a path?
skyhand dd ? 
endl 

invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE, .key,0,KEY_READ, addr skyhand 

.key db "SOFTWARE\Skype\Phone",0 
.value db "SkypePath",0 
endp    
Post 20 Jun 2007, 15:27
View user's profile Send private message Reply with quote
jumpex



Joined: 29 Jan 2006
Posts: 38
jumpex 20 Jun 2007, 15:45
The only things I found about procedures and local variables in them in the documentation were very few and didn't give me an answer. Could you quote where should I look?
Moreover - i tried with 'addr ', but that didn't work. The same error appears. Nothing different. As if 'addr ' wasn't there. I'd be HAPPY to read the part of the documentation you give me if I will find an answer there. I'm not lazy. Before I decide to post here, I look in GOOGLE, in my books about assembly, in FASM.PDF, in the documentation here, at flatassembler,net and the message board. Never thought that I couldn't find what I was looking for if it was there. But maybe it's my mistake. So, again, could you Quote the place, where procedures are covered in detail? Thank you.
Post 20 Jun 2007, 15:45
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Jun 2007, 16:03
http://flatassembler.net/docs.php?article=win32
Quote:
2.1 Procedure parameters
.
.
If the parameter is preceded by the addr word, it means that this value is a double word address and this address should be passed to procedure, even if it cannot be done directly - like in the case of local variables, which have addresses relative to EBP register, in such case the EDX register is used temporarily to calculate the value of address and pass it to the procedure. For example:

invoke RegisterClass,addr wc

in case when the wc is the local variable with address EBP-100h, will generate this sequence of instructions:

lea edx,[ebp-100h]
push edx
call [RegisterClass]

However when the given address is not relative to any register, it is stored directly.


In "1.3 Procedures" you have the documentation about procedures and talks about stdcall and invoke.

To use addr you have to include the extended headers (win32{a|w}x.inc). See "2. Extended headers" also.

I think the documentation covers more or less all one needs to code with those headers but if something is missing ask.
Post 20 Jun 2007, 16:03
View user's profile Send private message Reply with quote
jumpex



Joined: 29 Jan 2006
Posts: 38
jumpex 20 Jun 2007, 16:16
Hey... thank you for pointing that out, I've read it. This was what I was missing:

Quote:

To use addr you have to include the extended headers (win32{a|w}x.inc). See "2. Extended headers" also.


I'm sorry if I sounded rude, but I really try not to seek help. I read that part of the documentation so many times and tried with the addr in every single way. The tip (about variables and run-time) is also very helpful. Really grateful. Sorry again. And thank you.

P.S: Works. I'll search even harder from now on.
Post 20 Jun 2007, 16:16
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22 20 Jun 2007, 16:25
As an aside to this RTFM thread what is everyones view about local variables ?

For PROCs that are NOT thread-safe or recursive (HLL equiv of PUBLIC STATIC/FINAL) I tend to define local variables in my .data section.
PROs: No stack based addressing, reusable global TEMP variable
CONs: Possible source maintainability issues

I don't use the PROC macro NOT because of some bloated sense of preserving the natural flow of assembly, but because I don't think it's all that useful.
Post 20 Jun 2007, 16:25
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Jun 2007, 17:37
Quote:
PROs: No stack based addressing, reusable global TEMP variable

OK, you're not wasting time in creating a stack frame but you are using absolute addressing which makes instructions longer and hence preventing the CPU of decoding more instructions on some situations. Apart of that:
2. Optimizing subroutines in assembly language
An optimization guide for x86 platforms By Agner Fog. wrote:
4.2 Data storage
Variables and objects that are declared inside a function in C or C++ are stored on the stack
and addressed relative to the stack pointer or a stack frame. This is the most efficient way of
storing data, for two reasons. Firstly, the stack space used for local storage is released
when the function returns and may be reused by the next function that is called. Using the
same memory area repeatedly improves data caching. The second reason is that data
stored on the stack can often be addressed with an 8-bit offset relative to a pointer rather
than the 32 bits required for addressing data in the data segment. This makes the code
more compact so that it takes less space in the code cache or trace cache.


The reusability of TEMP var you mention as a PRO doesn't add anything to the stack based method since it always reuse stack space and automatically.

Anyway, I agree that it's not required to use PROC macro for every procedure you have, someones are better to implement with ESP based frame and these headers doesn't support it and sometimes a register based arguments passing is better than the stack based one.
Post 20 Jun 2007, 17:37
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22 21 Jun 2007, 00:03
Loco, the reusability was on the programming side, if your making a lot of PROCs it's slightly more convenient then allocating a local in each PROC; that PRO was definetly subjective.

But after some benchmarking the Global Vs Local temp var speeds vary a lot (sometimes local is faster sometimes global) but on average the local is faster. With arrays the local version is much faster. Although you can't make a very large array using the stack. Guess I'll have to change my bad habit Razz
Post 21 Jun 2007, 00:03
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.