Hi all,
I am trying to get my head around pointers in asm
esp and [esp] .. Which one is the contents of the register and which one is the memory address of the register ?!
Regards.
esp : This register is pointing a memory address.
[esp] : the content of the esp register
esp is a special register pointing the address of an important memory portion, the stack.
Similarly, eax,ebx,ecx,edx,esi,edi and ebp can indicate addresses or other values. In your case, the memory address of [esp] is the register esp itself.
There is no memory address of a register! Unless you're a low-level chip designer. Inside instructions its "address" is 7, but I don't think you're interested in that.
"esp" will refer to the contents of the register, such as 0, 1, 0c765ff0h, etc. IF it has a number like the last one, then [esp] will refer to the contents of the memory at 0c765ff0h (for instance). IF it has a number like the first two, then [esp] will cause an error; unless you're using register arithmetic ...
Hope that clears it up a bit
While typing this vortex also replied - I guess this is still relevant, another slant on same facts
Thank you both
Can I deduce from your statements that a register such as esp MUST ALWAYS contain a valid memory address ?
ok.. after re-reading the answers, I think I understand now
Again, thank you for your kind assistance
This is your rough distinction with a register.
ESP contains a value, specifically the address of the current stack location.
The notation [esp] is what is contained AT that address.
The first is the address, the second is the content at that address.
hmmm ... didn't really read Vortex's answer b4 but on the face of it he seems to be saying the opposite!
Vortex:
Quote[esp] : the content of the esp register
me:
Quote"esp" will refer to the contents of the register...
you: "so which is the contents, [esp] or esp ???
Well ... I'm sure what I'm thinking is right, whether I'm expressing it well is another story; makes sense to me, but Vortex may have a different understanding of the word "content", ...? Here's my solution: wait for dedndave to sort it out!
Anther reply happened again while I'm typing, but I'm 2 tired to see what it says ...
ps I agree with hutch, of course, so as far as I can see that makes it 2 to 1 ;)
probably just an issue of semantics
It is a simple notation issue, in MASM which uses the historical Intel notation, a 32 bit register holds a 32 bit value. When you enclose it in square brackets it refers to the content at an address. The address must be a valid address or you will try to read or write to an address that is not allocated to the current running process and you will get a protected mode page fault.
that's not what I meant, rather the reason Vortex seems to be saying the opposite of you and me is probably semantics; like, he's using the word "content" and thinking of "address", or something.
BTW not to pick nits .. well, actually, to pick nits: esp doesn't have to have a legal stack address! There's a technique where you use it as an 8th GP register and carefully don't touch the stack while doing so. I think Mark Larson mentions it. The idea is, for a really demanding algorithmic situation, free up that 8th register temporarily.
i can assure you that Erol (Vortex) knows the correct answer
but, his text is misleading
either he goofed up, or it's a simple language barrier (English is not his primary language)
use Hutch's explanation, instead (Reply #5) :P
.data?
esp_ dd ?
.code
....
mov esp_, esp
....
mov esp, esp_
make sure you have written everything off the stack first in a proc.
In some cases you have to specify:
- dword ptr[ESP] or
- byte ptr [esp]
- ...
Depends on the amount of bytes from memory you are referring to..
But usually EBP is used to read from the stack.
i.e. :
;-----------
push ebp
mov ebp,esp
mov eax,[ebp+4] ; same as mov eax,dword ptr[ebp+4]
mov bx,[ebp+8]
mov ecx [ebp+10]
....
pop ebp
;---------
Or.. Maybe I'm wrong.. You'd probably be better off using general purpose registers instead of EBP
Everything written above is correct. But you'd learn a lot if you assembled the snippet below and ran it with Olly.
include \masm32\include\masm32rt.inc
.code
start:
push 12345678h ; this decrements esp by 4 bytes and fills the memory pointed to by esp with 12345678h
mov eax, [esp] ; eax now holds 12345678h
mov edx, esp ; edx points to the current stack, like esp
mov ecx, [edx] ; ecx now holds 12345678h
pop edx ; get the content of the stack in edx (123..), and increment esp by 4 bytes
exit
end start
Thanks everyone for their guidance
Coming from a Visual Basic background, the subject of pointers and variable addresses is a kind of an intimidating tabou :)
VB is easier to learn and work with mainly due to the fact that it isolates the programmer from dealing with pointers .. VB does most of the addressing dirty work for you behind the scenes .. But this comes at a high price particularly when one wants to achieve advanced functionality (in VB) such as programming the Windows API and/or using some advanced COM technics
I am sure, I now have a better understanding .. so ,again, thanks everyone for their input :)
My apologies to AssemblyBeginner if I am wrong. Probably, my mistake as a non-native English speaker.
esp : the content is a memory address, the stack
[esp] : the value stored by the memory address pointed by esp
Its only a semantic issue, what Erol said here is correct.
esp : This register is pointing a memory address.
[esp] : the content of the esp register
ESP The stack POINTER. We all know ESP can be used as a general purpose register if its set up very carefully but its designation as a POINTER is its common usage.
Fortunately Erol's English is far better than my Turkish so all I can say is "yavaş yavaş", (slow slow), we deal with people from around the world here. :biggrin:
Quote from: iZ! on March 08, 2015, 02:09:41 AM
But usually EBP is used to read from the stack.
One detail that seems to have been forgotten here is that for indirect memory operands that reference (E)BP the default segment register is SS instead of DS. This detail does not matter under Windows, were SS == DS, but did matter under 16-bit DOS for memory models where SS != DS, where to access the stack you had to use BP or an explicit SS segment override.
Quote
Or.. Maybe I'm wrong.. You'd probably be better off using general purpose registers instead of EBP
In my test, timing access to memory allocated from the stack through EBP and ESI, comparing this code:
mov ecx, 100
@@:
mov eax, [ebp+ecx*4]
dec ecx
jnz @B
To this:
mov ecx, 100
@@:
mov eax, [esi+ecx*4]
dec ecx
jnz @B
And running on a Core-i3 typical results were
118 cycles, EBP
118 cycles, ESI
118 cycles, EBP
118 cycles, ESI
118 cycles, EBP
117 cycles, ESI
QuoteOne detail that seems to have been forgotten here is that for indirect memory operands that reference (E)BP the default segment register is SS instead of DS.
- No doubt others forgot it, but not me, since I didn't know it
hadn't forgotten - but they point to the same address space in win nt :t
include \masm32\include\masm32rt.inc
.data?
var dd ?
.code
start:
mov var , 1000 ; stores the value '1000' in the 32-bit integer stored at location var
print str$(var),13,10
mov [var] , 2 ; stores the value '2' in the 32-bit integer stored at location var
; same as (mov var , 2)
print str$(var),13,10 ; returns 2
inkey "Press a key to continue ..."
invoke ExitProcess, 0
end start
As you all can see in the code above, moving a value into the variable var can be achieved via :
mov var , somevalue
as well as
mov [var] , somevalue
Both methods seem to be the same .. How can that be ?!
Based on the answers given to the question on this post, I thought that putting a variable between brackets (ie:[var]) referred to the contents at the address var .. whereas
var referred to the actual variable address
Or is this just true for registers and NOT for variables ?
I hope I have explained the problem well ... Thank you
Hi,
Quote from: AssemblyBeginner on March 11, 2015, 07:33:35 AM
Both methods seem to be the same .. How can that be ?!
For variables the two are the same.
Quote
Or is this just true for registers and NOT for variables ?
Exactly. Registers are different from variables in that respect.
HTH,
Steve N.
Quote from: FORTRANS on March 11, 2015, 08:36:34 AM
Hi,
Quote from: AssemblyBeginner on March 11, 2015, 07:33:35 AM
Both methods seem to be the same .. How can that be ?!
For variables the two are the same.
Quote
Or is this just true for registers and NOT for variables ?
Exactly. Registers are different from variables in that respect.
HTH,
Steve N.
Thanks steve N,
Does this apply to instructions other than
mov such as
Push, Pop, add , sub , and , or ..etc ?
it does
for MASM, we generally only use brackets with registers
however, GoAsm (and perhaps some other assemblers) use brackets on all memory operands
the reason i mention this is, you may have seen code in the forum with brackets on names
that code is usually for the GoAsm assembler - check which sub-forum it's in :t
Its pretty simple, MASM ignores brackets around variables where other assemblers use that notation. Brackets around registers is what MASM will recognise and it means specifically the CONTENT at the ADDRESS in that register.
Thank you