News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Iczelion uses stack instructions instead of simple mov instruction

Started by test1, September 05, 2013, 08:25:08 PM

Previous topic - Next topic

test1

Why on Icezelion's Win32 assembly tutorial series he uses in stack instructions and not a simple mov.

push hInst
pop wc.hInstance

instead of
mov wc.hInstance, hInst

there's a simple answer for that? or he just smartass over

jj2007

Why don't you just try to assemble mov wc.hInstance, hInst ?
Or search \masm32\macros.asm for "m2m" and "mrm".

dedndave

mov mem32,mem32 won't work, as Jochen pointed out   :P
there are ways to perform 32-bit memory to memory transfers, but not really what you are interested in
one way is to use the stack

the method shown uses a few clock cycles, but makes smaller, simpler coding
another way - probably slightly faster - would be to use a register
mov eax,hInstance
mov wc.hInstance, eax

because this is a one-time operation, speed isn't critical
so the smaller, push/pop is probably a better choice - and it doesn't use a register

hutch--

Hi test1,

What you have been told is correct, Intel mnemonics do not support memory to memory copy directly so you either use a register as Dave has suggested OR you can use the stack which does not require a register at all.

Something that needs to be kept in mind, when you call a Windows API function, it is much slower than a direct assembler instruction as it branches to a DLL and runs many instructions to perform that function. Loading a structure to pass arguments to an API function is not time critical so it makes sense not to use a register if you don't need to.

Now if you were writing a speed critical algorithm, the stack is too slow and in that context you would use a register to copy the memory, its a case of picking what works to best in the context you are writing the code.

Mikl__

There is value of hInst equal 400000h in exe, why we can not use command mov wc.hInstance,400000h ? sorry for my english

dedndave

you can do that
but - what happens to the program if it is something different - crash ?
a call to GetModuleHandle works every time   :t
    INVOKE  GetModuleHandle,0
i guess that's 7 bytes - and that function is very fast

Mikl__

Hi, dedndave!
If you do not specify a link / BASE: address different from the address 400000h, then for the EXE hInstance = 400000h, and there is no need for GetModuleHandle

dedndave

 :biggrin:

ok - here is my question....

it is only executed once
as i mentioned, it takes ~7 bytes (really more like 4, because 400000h takes 4 bytes and EAX takes 1)
so - what are you saving by hard-coding a handle ????

what if they change it on windows 18 ? - lol

Mikl__

ok - here is my answer ....

assembly language programming is just a sporting interest and when MicroSoft release enterprise Windows 18 I'm likely to stop programming

Antariy

Quote from: dedndave on September 27, 2013, 12:02:25 PM
:biggrin:

ok - here is my question....

it is only executed once
as i mentioned, it takes ~7 bytes (really more like 4, because 400000h takes 4 bytes and EAX takes 1)
so - what are you saving by hard-coding a handle ????

what if they change it on windows 18 ? - lol

If the "standard" base address (400000h) would be changed, and/or that place would not (for any reason) be provided for the program, then every program that linked without relocations table will not even be executable at all - Windows will unable to start it. If MS will do this - it will break compatibility with much of early-era (~pre-2005) Win32 software. Also with no difference to that, all the MASM32 programs using the default package linker would not be executable, too, because the linker uses the "standard" base address and doesn't generate relocations by default. To force generation of relocs with the linkers version below than 8, use command line option /FIXED:NO
Until your EXE contains relocations - you may freely use hardcoded EXE "handle" because there are only two options that Windows may do with EXE without relocations: provide the space that specified in the PE header as the base address and execute program - so the hardcoded handle will be valid, or if the Windows fails to provide that space, it just would not execute the program.

This is the reason, for an instance, why MemInfoMicro (crafted exe) is able to specify the module handle to the MessageBoxIndirect (the graphical indicator is the resource) and at all runs on modern Windows with ASLR.

Yes, MS seems to go the way when they may drop the "support" of the EXEs without relocs, but then 99% of our already-in-binary assembly programs would not work :lol:

sinsi

Also, if you build a 64-bit exe the start address is likely to be 0000000140000000.
The API is there for a reason, use it  :biggrin:

Gunther

You have to know the facts before you can distort them.

Antariy


GetCurrentModuleHandle proc
   call @F
   xor ax,ax
   ret
   @@:
   pop eax
   push eax
   ret
GetCurrentModuleHandle endp

; after a call EAX contains the handle of the module that contains the code



Make sure you place the proc above as close to the start of the sources (it's better to make it as an include which one will include first in the program before any other includes / code. The reason is: every module is mapped with 64 KB boundary, so, having call in the first 64 KB of the executable image (EXE/DLL) mapped in the memory, and masking lowest 16 bits of the return address, we have the module handle. This will work for EXE/DLL on any Win32 system - the only requirement the proc should be close to the start of the module image.

japheth

Quote from: Mikl__ on September 27, 2013, 10:32:59 AM
There is value of hInst equal 400000h in exe, why we can not use command mov wc.hInstance,400000h ? sorry for my english

Just one instruction cannot reliably replace GetModuleHandle().

But 2 might do the job:


.386
.model flat

printf proto c :vararg

CStr macro x:vararg
local y
.const
y db x,0
.code
exitm <offset y>
endm

.code

_start:
mov eax, _start
sub eax, imagerel _start
invoke printf, CStr("module=%X",10), eax
ret


end _start