Re: copymemory basic question



"Tony Proctor" <tony_proctor@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:OixEY55rFHA.1168@xxxxxxxxxxxxxxxxxxxxxxx
>
> When a procedure is called, a pre-amble usually allocates all the stack
> space required for local stack-based variables (i.e. 'Dim' variables in
> VB).
> Allocation of the space is done in one go, and tearing it down on
> procedure
> exit is also done in one go.

I think 16-bit Windows had things such as preambles that were requrired for
functions that Windows calls. Other than that, I don't recall the term being
used in the context of assembler language.

Some VB Subs and Functions have no code that pushes and pops anything nor do
they do any initialization/termination code other than the return
instruction of course.

To "allocate" local variables, VB simply reduces the amount of available
stack space in order to make room for local variables. It does that in a
single subtraction machine instruction regardlous of the quantity and size
of local (Dim) variables, as in:

sub esp,7Ch

However VB attempts to use registers instead of memory for local variables.
In other words, the following code:

Public Function OptimizedTiny() As Integer
Dim DynamicLocal As Integer
DynamicLocal = &HDEB1
OptimizedTiny = DynamicLocal
End Function

Gets compiled down to a single machine instruction (excluding the return
instruction), such as:

mov ax,0DEB1h

I use the value "0DEB1h" (&HDEB1) so that I can find the code in the machine
code listing. I compile the code prior to dis-assembly in order to get the
compiled code. I created a small test project with just a module and later I
added a class. I compiled the project and then dumped the exe using:

DUMPBIN /DisAsm /Out:Dump.txt StaticCode.exe

> A bigger hit may be experienced with
> initialised variables, especially objects, strings, and arrays. This is
> because the code required to initialise them, and then deallocate their
> dynamic memory on exit, is very significant.

It depends and probably personal preference is one influence. I think that
for many situations, probably most, the time required to initialize a
varible (a Dim) is rarely significant, but can be significant.

> For a procedure in a Module,
> the memory allocated for a static variable forms a permanent contribution
> to
> the Thread Local Storage (TLS).

I am not real familiar with TLS. I know that for VC programming there can be
problems using DLLs due to TLS. I have searched for information about VB
using TLS and it does seem that it is important to know about TLS for
advanced VB programming. I do not find anything that clearly specifies
everything that VB uses TLS for. I think the VB documentation says nothing
about TLS. Where is it said that TLS is used for static variables in
procedures in a Module?

> When a stack variable is accessed, it's always via an offset-off-register
> addressing mode, usually BP but sometimes SP if call frames have been
> optimised out. This is a really quick addressing mode.

Do you mean static variables for a form's processing? I did not try that but
I did for the other two possibilities below.

> For Static variables
> in a Module, the variable is accessed by loading up it's 32-bit address
> and
> referencing it directly. The instruction sequence to load the address is
> bigger and uses both extra space and processor cycles.

For the following code:

Public Function TestFunction() As Long
Static StaticLocal As Long
Dim s As String
StaticLocal = StaticLocal + &HDEB0&
TestFunction = StaticLocal
s = Hex(StaticLocal)
MsgBox "We are at: " & s
End Function

The statement "StaticLocal = StaticLocal + &HDEB0&" resulted in the
following two machine instructions:

mov eax,[00403014]
mov ecx,dword ptr [eax]

When I had more than one Static variable, the insructions were similar
except a different register was
used and I think offsets were used. The generated code was slightly
innefficient because it loaded the
same value multiple times into the same register without the register being
set to anything else in
between. This is relatively minor inneficiency.

However VB's use of registers for non-static (automatic?) variables I think
can result in the most
efficient code possible. That probably applies only to Integer and Long
types, however it is possible
(I just did not try) that the floating point registers are used in a similar
way for doubles and such.

> As for static variables in
> a class, I'd be interested to know what code the VB compiler generates. It
> should be efficient since it's accessing a location relative to the class
> instance's memory aggregate, but then it doesn't seem to generate optimal
> code in other cases.

When I created a class and put the TestFunction (as above) into it, the code
generated for the assignment
statement is:

mov esi,dword ptr [ebp+8]
mov eax,dword ptr [esi+38h]
mov ecx,dword ptr [eax]


.