EBP doesn't get modified by push/pop instructions, it's setup manually, so unless you change it yourself it will just stay the same.
Up vote 3 down vote favorite share g+ share fb share tw.
I am learning High Level Assembly language at the moment and have been going over the concept of the stack. I think I understand it fairly well, however in practice I have some questions. The stack grows down, with the ESP register always pointing to the top of the stack..an address in low memory.
If something is pushed onto the stack, then ESP should be decremented. EBP is useds as a frame pointer and as to my understanding, should always be more than ESP. Yet, with the following program: stdout.
Put(esp, nl); stdout. Put(ebp, nl); push(ike); stdout. Put(esp, nl); stdout.
Put(ebp, nl); push(ike); stdout. Put(esp, nl); stdout. Put(ebp, nl); pop(eax); pop(eax); pop(eax); pop(eax); stdout.
Put(esp, nl); stdout. Put(ebp, nl); This does not seem to be the case. Looking at the output: 0018FF6C 0018FF70 0018FF68 0018FF70 0018FF64 0018FF70 0018FF74 0018FF70 EBP is always the same, ESP is decremented by 4 bytes for the first push, then another 4 bytes for the second push.
It is after this I am confused. After my first 2 pops, ESP should be back to where it started. How can I then do a further two pops if I have not pushed anything on to the stack?
What am I popping? Further popping and printing out of EAX shows some numbers, and then 0's and then further numbers. So, I am definitely popping something...but what?
What part of my program memory does it belong to, and why is nothing being affected? Why is EBP not being affected at all? Also, why is ESP being decremented by 4 bytes, and not by 8?
If someone could help me to understand this, I would be most grateful. Assembly stack link|improve this question asked Aug 24 '11 at 11:54Jason Sill854 70% accept rate.
EBP doesn't get modified by push/pop instructions, it's setup manually, so unless you change it yourself it will just stay the same. The pushes of IKE are resulting in 4-byte changes, so apparently you're in 32-bit mode here. The 4 pops of EAX (32-bit) will result in a 16-byte (10h) change, just like they do.
Not sure what the problem is here. Seems to be working as I expect?
I have no doubt it is working as it is meant to, it's just that I don't understand it. I thought that while EBP was setup manually..., if not done so it was also used internally sometimes? I would have thought ESP would decrement a byte at a time, not 32 bits at a time?
– Jason Sill Aug 24 '11 at 12:40 My main question is why I can continue to pop things of the stack that I didn't push on. Essentially, if I remove the push insctruioncs from my program, why can I pop without having pushed? What am I popping?
I am popping of the stack into EAX, but I am not sure what it is I am taking from the stack. – Jason Sill Aug 24 '11 at 12:42 A further question about EBP...I thought it was always part of the stack, before the return address... – Jason Sill Aug 24 '11 at 12:45 EBP is just a register. Typically used for indexing items on the stack (due to standard conventions).
If you really want, you can use it for other things though. Nothing magic about it. If you're pushing/popping 32-bit items, ESP will change by 32-bits.
It's a pointer, NOT an item counter. It has to point to the proper part of memory, therefore it must change by the size of the operands. The processor is more than happy to pop until it can't pop anymore.
Pop is basically just a MOV then ADD ESP, operand size in bytes. Real mode, it'll wrap. Protected may segfault eventually... – Brian Knoblauch Aug 24 '11 at 12:54 SO using EBP as a frame pointer is just convention, and always done manually -- never internally?
It was my understanding that if you coded in a high level language and disassembled, you would see EBP being used. I get that the processor is happy to pop...but what is it popping? Data from other programs?
From operating system memory space? – Jason Sill Aug 24 '11 at 13:08.
The stack is used to hold, besides the things you push and pop, every function's stack frame (i.e. Local variables), return address, the old ebp (specifically where the current ebp is) and function's parameters. So what you're popping out is the stack frame of your function.
If you disassemble a program, you'll see: push param3 ; suppose func takes 3 parameters, they're push param2 ; pushed in reversed order (C-style) push param1 call func ; call pushes also the return address, i.e. The ; address of the instrucion after the call ... func: push ebp ; this is done for preserving the caller's stack frame mov ebp, esp ; now we set up the beginning of func's stack frame sub esp, smth. ; and its width, enough to fit all func's variables At this point the stack will be something like: 00000058: arg3 00000054: arg2 00000050: arg1 0000004c: return address ebp -> 00000048: caller's ebp ... ... - 00000034: random stuff | func's stack frame, random because they 00000030: random stuff | are uninitialized esp -> 0000002c: random stuff - Finally, you push and pop only 4 bytes at time because that's the word size of your machine, this way you can save entire registers.
In one shot.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.