Hi.  Sorry if my question seems trivial, but I need to know the answer in order to progress!  I think I'm asking a question relating to indirect addressing, but I'm not sure.  Here goes...

I have allocated 4K of memory using VirtualAlloc.  The location of this memory has been mov'd into pTable using the following code:


LOCAL pTable: DWORD
  .
  .
  .
invoke VirtualAlloc, NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE
mov pTable, eax


This works fine with the memory being allocated and the pointer being stored in the pTable variable (verified with OllyDbg)

I now want to write some dword values to this newly allocated memory, treating it as a table.  Here is the code I am using now to store a value at the first dword offset of the table:


mov ebx, pTable
mov dword ptr , eax


The above code is functional, but I don't see why I can't just use the following:


mov dword ptr , eax


The above code simply overwrites the value stored in pTable, effectively losing my pointer to the table.  Can anyone explain why the second method doesn't work and/or how this could be written better?
Posted on 2006-09-11 00:09:56 by Timbo
The first case is correct because you are loading a value from memory using "pTable" as the memory reference (pointer), and using that value as a memory reference itself.

The second example will not work because you are using "pTable" as the memory reference, which is why you are overriding it.

Here is an example in NASM syntax (which I find more uniform and clear in this case)...


;LOCAL pTable
pTable DD 0

;First Case
mov ebx, DWORD ;***** This illustrates the difference *****
mov DWORD, eax

;Second Case
mov DWORD, eax


If you notice in the above code, the first instruction of the first case uses the same principles as the first instruction of the second case, that being "pTable" as a memory reference.

This is something that MASM "hides" for you by keeping track of variable references and accessing them in a C-like manner (directly addressing the value of a variable, not the pointer/address of it). Thus, "mov ebx, pTable" is the equivalent of "mov ebx, dword ptr ". I think the main reason being, is that MASM was further designed in mind to be used as an intermediate stage for compilers... this is where referencing values of variables instead of their pointer/address becomes easier.

For example, it is much easier to write "invoke MyFunction, pTable" instead of "invoke MyFunction, dword ptr "... imagine having to do that for every variable value you wish to reference. For most people who are debugging/reading their ASM equivalent code, it would get annoying to read the same thing over and over ("dword ptr " ad-infitium).

In the end, MASM is a pretty good assembler... as long as you are aware of its idiosyncrasies.
Posted on 2006-09-11 01:58:06 by SpooK
Thanks for the quick reply.

I should have mentioned I was using masm but I guessed you figured it out :)

So, if I understand correctly, the nasm syntax:


mov dword, 1000H


places the value 1000H in the memory address referenced by the data stored in ebx.  So, for example, if the ebx register held the value 30000H, the above instruction would move the value 10000H to the memory location 30000H.  I hope I got that right.

The main reason why I preferred the look of the second method was that it only used 1 instruction.  Is there way, using masm, to reference (or store data in) the memory location pointed to by pTable using 1 instruction?  Or am I better off using the first method, i.e. using the ebx register to temporarily hold the location?
Posted on 2006-09-11 04:05:21 by Timbo
     All my code has the following header statements

Q        EQU     QWORD PTR
D        EQU     DWORD PTR
W        EQU     WORD PTR
B        EQU     BYTE PTR


     So I code like this:

  PUSH W
  MOV AL,B
  ...ETC


Ratch
Posted on 2006-09-11 09:49:37 by Ratch
My code is very close to what Ratch does:


a$ TEXTEQU <ADDR>
b$ TEXTEQU <BYTE PTR>
d$ TEXTEQU <DWORD PTR>
w$ TEXTEQU <WORD PTR>
s$ TEXTEQU <SIZEOF>
o$ TEXTEQU <OFFSET>



mov eax, o$ szTemp
mov d$, edx


It adds readability.
Posted on 2006-09-11 10:27:22 by JimmyClif

The main reason why I preferred the look of the second method was that it only used 1 instruction.  Is there way, using masm, to reference (or store data in) the memory location pointed to by pTable using 1 instruction?  Or am I better off using the first method, i.e. using the ebx register to temporarily hold the location?


On the x86, register values (your first post) and immediate values (your 2nd post) that get moved into memory require an effective memory address. That memory address will always be direct, not a pointer to a pointer. So no, you are suck with the first method.

If you find yourself reloading a register with a memory value (like the "pTable" stored pointer) one too many times, you have to re-think and re-design the way you are programming. This is usually were functions/subroutines come in to play.

As for Ratch/JimmyClif's examples, it just reinforces why I will never program in MASM/POASM unless forced to. Using one abstraction to mask another was never my style. Basically, **** or get off the pot... but as I said... that is just my style ;)
Posted on 2006-09-11 10:35:29 by SpooK
so, back to the topic:
to fill your array with values, there are two common ways:
(example of filling the array with values 0...1023)

mov ebx,pTable
xor ecx,ecx
.while ecx<1024
    mov ,ecx
    inc ecx
.endw


mov ebx,pTable
xor ecx,ecx
.while ecx<1024
    mov ,ecx
    inc ecx
    add ebx,4
.endw
Posted on 2006-09-11 14:38:22 by Ultrano

The main reason why I preferred the look of the second method was that it only used 1 instruction.  Is there way, using masm, to reference (or store data in) the memory location pointed to by pTable using 1 instruction?  Or am I better off using the first method, i.e. using the ebx register to temporarily hold the location?

You cannot use "one" instruction unless you create a macro (a fake instruction) that will generate two real instructions. The CPU itself does not support indirect addressing via memory for data.
Posted on 2006-09-11 21:04:28 by tenkey
Thanks to everyone for replying.

@SpooK: You are correct in saying that I need to rethink and redesign my programming method.  I come from a basic/pascal background and I am beginning to realize that there is more going on "under the hood" when using high level languages than is immediately apparent.  I'm fairly new to assembler so this is all a learning experience at the moment.

@Ultrano: Thanks for the sample code.  That's exactly what I wanted to do (i think).  The solution seems so obvious now, I just have to rethink my approach and make more efficient use of the instruction set and registers.

@Ratch & JimmyClif: I wasn't aware of that little trick.  Thanks!

@tenkey: The idea of a macro sounds like a viable alternative, I'll give it a go.

I'm beginning to think that maybe masm is not the best flavour of assembler to start learning in.  From the look of some other posts in this forum, nasm seems to be the assembler of choice and as many of you have mentioned, the code is clear and the intent more obvious.  Either way, a quick look at the disassembly in OllyDbg displays the code as it is.  At least I understand the concept now.  I'm impressed at the quality of the replies so thanks again for your help guys!
Posted on 2006-09-12 04:59:23 by Timbo

@SpooK: You are correct in saying that I need to rethink and redesign my programming method.  I come from a basic/pascal background and I am beginning to realize that there is more going on "under the hood" when using high level languages than is immediately apparent.  I'm fairly new to assembler so this is all a learning experience at the moment.


No problem. Just keep in mind that high-level languages usually keep track of variable lifetime for you, which is calculated in to the optimizations. In Assembly Language, you have to exercise complete control. How/when you access a variable (or any data in memory/registers) is static, meaning that once you put that instrunction there... it stays there. You are the optimizer now ;)

It takes a bit to get used to, but eventually you will feel "naked" when programming in HLLs :P
Posted on 2006-09-12 12:57:53 by SpooK
It takes a bit to get used to, but eventually you will feel "naked" when programming in HLLs


I don't know about you, but I feel the opposite way.. I feel 'stifled and suppressed' in the rare event that I find myself coding under a HLL, as if I was wearing two fur coats and three pairs of gloves (or perhaps a strait jacket?)
When I code in asm, I feel 'free and empowered', which is probably closer to 'naked', depending on your interpretation of the word.
Evidentally, I don't have a problem with being 'naked' :P


Posted on 2006-09-13 03:16:15 by Homer

The above code is functional, but I don't see why I can't just use the following:


mov dword ptr , eax

you got fooled by stupid HLLish MASMy syntax, where "mov a, eax" is same as "mov ,eax". IMHO too many things are uncertain and context dependant in MASM, no general rules.
Posted on 2006-09-13 03:45:36 by vid
@vid: That's what I'm starting to realize.  I thought that would dereference pTable in the same fashion as => eax.  But I understand now, it's a masm thing.

@Homer: What's the saying?  With great power comes great responsibility.  When you're coding at this level, as SpooK said, you have complete control and must handle everything.  There's no fancy optimizing or error checking unless implement it yourself.  So far I've found that in asm, there's a much smaller safety net to catch you when you screw it up.  The trade off, in my opinion, is worth it as it makes you think more about what you are doing and there's less bloat.
Posted on 2006-09-13 05:14:24 by Timbo

It takes a bit to get used to, but eventually you will feel "naked" when programming in HLLs


I don't know about you, but I feel the opposite way.. I feel 'stifled and suppressed' in the rare event that I find myself coding under a HLL, as if I was wearing two fur coats and three pairs of gloves (or perhaps a strait jacket?)
When I code in asm, I feel 'free and empowered', which is probably closer to 'naked', depending on your interpretation of the word.
Evidentally, I don't have a problem with being 'naked' :P


I meant like one of those dreams where you are in the middle of a crowd and they are staring at you because you are naked. You have know idea what to do... you just know you are not in control at the moment :P


The trade off, in my opinion, is worth it as it makes you think more about what you are doing and there's less bloat.


That is why most of us do it. Just don't get "too" caught-up in optmizations. Usually there are better algorthims that you can implement if you find yourself in the middle of an optimization nightmare. Design your program from the Top-Down (HLL type logic), and build it from the Bottom-Up (ASM programming) :)
Posted on 2006-09-13 09:23:44 by SpooK
Timbo: NASM fixed it, and later FASM took this fix. FASM has (much) less materials on internet, but also has very good support on it's board (you ask - we answer), so you could think about migrating to FASM. Or NASM, YASM, or just anything with syntax that's not designed as fake of high level languages syntax

You will encounter many more such things with MASM.
Posted on 2006-09-20 08:40:55 by vid