Hi,

I recently discovered a tool that will let you create inline assembly in visual basic. This has got me pretty excited but I've only been able to do pretty simple things in masm32 in the past. Masm32 makes building procedures a little easier than normal but because this assembly is effectivley inserted between the visual basic code, it uses the lowest level of assembler without some of the shortcuts that masm32 allows you to take.

Basically my problem is getting and setting parameter values. I would like to pass a variable to a procedure, have that procedure increment the value of the variable by one and then return the value in the variable passed to it. IE the variable is passed by reference. How do I code this in assembly? Here's what I've tried so far. Notice how the assembly code is commented out with the single qoute so that VB doesn't complain when you compile.



Public Sub increment(ByRef num As Long)
'#ASM_START
' push ebp
' push edi
' mov ebp, esp
'
'
' mov eax, [ebp+4]
' inc eax
' mov edi, DWORD PTR [ebp+4]
' mov [edi], eax
'
' mov esp, ebp
' pop edi
' pop ebp
' ret 8
'#ASM_END
End Sub


I belive the first parameter may actually be held in . I don't know if this is normal or if this is because of the way the asm code is inlined with the VB. Anyway, code someone give me an example of the correct way to do this?
Posted on 2004-04-12 20:02:08 by DeX
The way you push values on the stack before setting EBP determines the EBP offset. In your code, the stack after executing MOV EBP,ESP is ...
ebp+12: first argument

ebp+ 8: old EIP (return address)
ebp+ 4: old EBP
ebp+ 0: old EDI
I do not know why you are using RET 8. That assumes you have two arguments on the stack. The value 8 does not include the return address.
Posted on 2004-04-12 20:25:15 by tenkey
Ok, I finally got a bit further thanks to your help. This is my code to copy the contents of the first argument to eax. Is this the best way to do it?



mov eax, DWORD PTR [ebp+8]
mov eax, [eax]


I'm using ebp+8 now because I reversed the order that ebp and eip and pushed/popped to/from the stack. The code above works now. The first line puts the address of the argument variable into eax, the second puts the contents of that address into eax, but is there not a better way that might only use one line?

Also, the same goes for updating the value of the argument. This is what I am doing at the moment:



mov edi, DWORD PTR [ebp+8]
mov [edi], eax


Again is there a better way than the above?

Thanks
Posted on 2004-04-13 05:11:22 by DeX

I recently discovered a tool that will let you create inline assembly in visual basic.


Hi DeX,

How is it possible to get this tool?
Posted on 2004-04-13 05:20:35 by Vortex
Get it here:

http://www.persistentrealities.com/vbfibre/index.php

It's suprisingly easy to use. Just follow the steps on the 'Using Inline ASM' page.
Posted on 2004-04-13 05:54:30 by DeX
Thanks for the link:alright:
Posted on 2004-04-13 12:31:52 by Vortex
DeX,

Your code is as short as it can be.

However, you can reuse the loaded address...

mov edi,
mov eax, ; get argument
; further calculations not using EDI
mov ,eax ; update argument
Posted on 2004-04-13 21:03:21 by tenkey
Ok, I get it now. I was just having trouble keeping track of what the stack contained, what the registers contained and how changing to procedure from ByRef to ByVal affected things. Thanks.
Posted on 2004-04-14 15:12:54 by DeX