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:
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:
The above code is functional, but I don't see why I can't just use the following:
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?
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?
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)...
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.
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.
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:
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?
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?
All my code has the following header statements
So I code like this:
Ratch
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
My code is very close to what Ratch does:
It adds readability.
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.
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 ;)
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)
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
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.
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!
@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!
@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
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
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.
@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.
@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.
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) :)
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.
You will encounter many more such things with MASM.