Is it possible to read something from the middle of the stack, without "throwing out" elements from it, until we reach the middle?

UPD. Apparently, I put it wrong. In general, I want to understand how the stack works in the process. we have a program (written in C) that is running. and suppose there are several variables. they are created in the stack. right?

  • You can, let's say mov eax, [esp + 10] - nick_n_a
  • 2
    Depends on the stack implementation - Vladimir Gamalyan
  • Here you are for the IBM x86 processor's process stack mov eax, [esp + 10] - nick_n_a
  • Specify what you mean by the word stack. What environment are using, which library or processor. - nick_n_a
  • @nick_n_a specifically the organization of dynamic memory. percent 86. - some people

3 answers 3

Sure you may. The call stack is a continuous dataset containing local variables and possibly some other information. A local variable in a program is usually represented by an offset from the top of the stack (there is at least another variant with a register). Thus, access to data inside the stack is performed continuously. Well and still, it gives the chance to the called functions to spoil the top, after which nothing good will come out. But this does not seem to concern the question.

  • Does a variable call occur at a previously known address or by referring to a stack as a stack? - some people
  • @somepeople, in most cases - by offset from the top of the stack. The function does not know where it will be called, so it cannot know the exact address. - Qwertiy
  • @somepeople, Usually, when a function is called, a so-called Stack Frame is created , then the register (usually ebp) contains the address of the beginning of this frame. And all variables in the stack are addressed to a fixed offset [ebp + x] within this function. - Alekcvp
  • first, variables are created in the stack, then they are accessed (modified, read) by offset relative to the end of the stack. the issue is resolved - some people

For c ++ x86 32-bit response

CONTEXT ctx; ctx.Flags = CONTEXT_CONTROL; if (GetThreadContext(GetCurrentThread(),&ctx)) { int * stack = (int*) ctx.Esp; // получили массив стека, в котором можно увидеть значения локальных переменных // тут можно смотреть стек printf("%x", stack[0]); } 

For some versions with ++ you can get a pointer easier

 int * stack = (int*)_ESP; // borland c++ int * stack; // для тех версий что поддерживают asm, этот вариант так же не все поддерживают asm { mov eax; esp; mov dword ptr stack, eax; } 

Many environments support dump memory and the cpu window — you can visually examine the stack there.

And lastly, the barbaric way. Stack that is. You can take it and get an approximate stack address - by taking the address of a local variable (it is not equal to esp, but you can already analyze the stack):

 int a = 1; int b = 2; int * stack = (int*)&a; 

And see stack [0]; stack [1] and stack [-1];

I liked the organization of the stack: https://rsdn.ru/article/cpp/ObjectsAndPointers.xml with pictures.

  • So. Stop. and now another question: are the variables really created and stored on the stack? - some people
  • Local yes (including function / procedure parameters), global no. Obtained with new or alloc either. - nick_n_a
  • look, when we create a local type variable int, then another one. they are created in a row and the stack grows, right? - some people
  • Yes, right. And even more, taking the address of one, and adding it - you can write the value in the next. For example: int a = 0; int b [1]; int c = 0; b [1] = 1; / * Write to the next one, now either a or c (rather a) is 1 * /. Only need to use variables, because the compiler can throw out unused locale variables. At least display all three on the screen. - nick_n_a
  • but still the whole thing is stored on the stack. and how then is the access to the variables obtained if it is impossible to read from the last created cell? or is everything written to the addresses, what corresponds to what? - some people

not. unless, of course, you have a pointer to it, but there is a pointer only to the beginning of the stack

  • and if there is a pointer then yes? So yes or no. Or you need to specify that you need to clarify the question? - nick_n_a
  • When implementing a list, you always point to the beginning. you have a pointer to the beginning. This pointer can be changed to which thread is another element. but then the whole point is lost - Senior Pomidor
  • The answer is no longer relevant due to the clarification of the question. - Qwertiy