Каковы точно указатель базы и указатель вершины стека? На какой они указывают?

Возможно, Вы спрашиваете о хранении таких вещей, идущих...

, Конечно, Вы вызовете полное сканирование таблицы на предмет запросов и если таблица, содержащая очки, которым нужно соответствовать (агрегирования), является большой, Вы могли бы хотеть лучшее решение для выполнения, можно составить вторичную таблицу и использовать правила, такой как on insert - Вы могли бы изучить ее.

Не все механизмы RDBMS имеют правила, хотя!

214
задан Ciro Santilli 新疆改造中心法轮功六四事件 24 March 2019 в 00:10
поделиться

8 ответов

esp так, как вы говорите является вершиной стека.

ebp обычно устанавливается на esp в начале функции. Доступ к параметрам функции и локальным переменным осуществляется путем добавления и вычитания, соответственно, постоянного смещения из ebp . Все соглашения о вызовах x86 определяют ebp как сохраняемые при вызовах функций. Сама ebp фактически указывает на базовый указатель предыдущего кадра, что позволяет перемещаться по стеку в отладчике и просматривать локальные переменные других кадров для работы.

Большинство прологов функций выглядят примерно так:

push ebp      ; Preserve current frame pointer
mov ebp, esp  ; Create new frame pointer pointing to current stack top
sub esp, 20   ; allocate 20 bytes worth of locals on stack.

Затем в функции у вас может быть такой код (при условии, что обе локальные переменные имеют размер 4 байта)

mov [ebp-4], eax    ; Store eax in first local
mov ebx, [ebp - 8]  ; Load ebx from second local

FPO или упущение указателя кадра оптимизация, которую вы можете enable фактически устранит это и будет использовать ebp в качестве другого регистра и обращаться к локальным переменным непосредственно из esp , но это немного усложняет отладку, поскольку отладчик больше не может напрямую обращаться к кадрам стека из предыдущих вызовов функций.

РЕДАКТИРОВАТЬ:

Для вашего обновленного вопроса, в стеке отсутствуют две записи:

var_C = dword ptr -0Ch
var_8 = dword ptr -8
var_4 = dword ptr -4
*savedFramePointer = dword ptr 0*
*return address = dword ptr 4*
hInstance = dword ptr  8h
PrevInstance = dword ptr  0C
hlpCmdLine = dword ptr  10h
nShowCmd = dword ptr  14h

Это связано с тем, что поток вызова функции:

  • Отправка параметров ( hInstance и т. д.)
  • Вызов функции, которая передает адрес возврата
  • Push ebp
  • Выделить место для локальных жителей
220
ответ дан 23 November 2019 в 04:26
поделиться

ESP - это текущий указатель стека, который будет изменяться каждый раз, когда слово или адрес помещается в / из стека. EBP - более удобный способ для компилятора отслеживать параметры функции и локальные переменные, чем использование ESP напрямую.

Как правило (и это может варьироваться от компилятора к компилятору), все аргументы вызываемой функции являются помещаются в стек вызывающей функцией (обычно в порядке, обратном их объявлению в прототипе функции, но это может быть разным). Затем вызывается функция, которая помещает адрес возврата (EIP) в стек.

При входе в функцию старое значение EBP помещается в стек, а EBP устанавливается на значение ESP. Затем ESP уменьшается (поскольку стек увеличивается вниз в памяти), чтобы выделить место для функции ' s локальные переменные и временные. С этого момента во время выполнения функции аргументы функции располагаются в стеке с положительными смещениями от EBP (поскольку они были помещены до вызова функции), а локальные переменные располагаются с отрицательными смещениями от EBP. (потому что они были размещены в стеке после входа в функцию). Вот почему EBP называется указателем кадра , потому что он указывает на центр кадра вызова функции .

При выходе все, что нужно сделать функции, - это установить ESP на значение EBP (которое освобождает локальные переменные из стека и выставляет запись EBP наверху стека), затем выталкивает старое значение EBP из стека, а затем функция возвращает (выталкивая адрес возврата в EIP) .

После возврата к вызывающей функции, Затем он может увеличивать ESP, чтобы удалить аргументы функции, которые он поместил в стек непосредственно перед вызовом другой функции. В этот момент стек вернулся в то же состояние, в котором он находился до вызова вызываемой функции.

89
ответ дан 23 November 2019 в 04:26
поделиться

Вы правы. Указатель стека указывает на верхний элемент стека, а базовый указатель указывает на «предыдущую» вершину стека до вызова функции.

Когда вы вызываете функцию, любая локальная переменная будет будут сохранены в стеке, и указатель стека будет увеличиваться. Когда вы возвращаетесь из функции, все локальные переменные в стеке выходят из области видимости. Вы делаете это, устанавливая указатель стека обратно на базовый указатель (который был «предыдущей» вершиной перед вызовом функции).

Распределение памяти таким способом очень , очень быстро и эффективно.

15
ответ дан 23 November 2019 в 04:26
поделиться

РЕДАКТИРОВАТЬ: Для лучшего описания см. Дизассемблирование / Функции x86 и фреймы стека в WikiBook о сборке x86. Я пытаюсь добавить некоторую информацию, которая может вас заинтересовать при использовании Visual Studio.

Сохранение EBP вызывающего абонента в качестве первой локальной переменной называется стандартным фреймом стека, и это может использоваться почти для всех соглашений о вызовах в Windows. Существуют различия в том, освобождает ли вызывающий или вызываемый объект переданные параметры, и какие параметры передаются в регистрах, но они ортогональны проблеме стандартного кадра стека.

Говоря о программах Windows, вы, вероятно, можете использовать Visual Studio для компиляции кода C ++ . Имейте в виду, что Microsoft использует оптимизацию под названием Frame Pointer Omission, что делает практически невозможным обход стека без использования библиотеки dbghlp и файла PDB для исполняемого файла.

Этот пропуск указателя кадра означает, что компилятор не хранит старый EBP в стандартном месте и использует регистр EBP для что-то еще, поэтому вам трудно найти вызывающий EIP, не зная, сколько места требуется локальным переменным для данной функции. Конечно, Microsoft предоставляет API, который позволяет вам выполнять обход стека даже в этом случае, но поиск базы данных таблицы символов в файлах PDB в некоторых случаях занимает слишком много времени.

Чтобы избежать FPO в ваших модулях компиляции, вам необходимо чтобы избежать использования / O2 или необходимости явно добавлять / Oy- к флагам компиляции C ++ в ваших проектах. Вы, вероятно, ссылаетесь на среду выполнения C или C ++, которая использует FPO в конфигурации Release,

7
ответ дан 23 November 2019 в 04:26
поделиться

Давно я не занимался программированием на ассемблере, но эта ссылка может быть полезна ...

Процессор имеет набор регистров, которые используются для хранения данные. Некоторые из них являются прямыми значениями, а другие указывают на область в ОЗУ. Регистры, как правило, используются для определенных действий, и каждый операнд в сборке потребует определенного количества данных в определенных регистрах.

Указатель стека в основном используется, когда вы вызываете другие процедуры. В современных компиляторах сначала в стек будет выгружена пачка данных, за которой следует адрес возврата, чтобы система знала, куда вернуться, как только ей будет приказано вернуться. Указатель стека будет указывать на следующее место, где новые данные могут быть помещены в стек, где они будут оставаться до тех пор, пока не будут возвращены обратно.

Базовые регистры или сегментные регистры просто указывают на адресное пространство большого объема данных. В сочетании со вторым регистром базовый указатель разделит память на огромные блоки, а второй регистр будет указывать на элемент в этом блоке. Базовые указатели для этого указывают на базу блоков данных.

Имейте в виду, что сборка очень зависит от процессора. Страница, на которую я указал, предоставляет информацию о различных типах процессоров.

1
ответ дан 23 November 2019 в 04:26
поделиться

Прежде всего, указатель стека указывает на нижнюю часть стека, поскольку стеки x86 строятся от высоких значений адреса к нижним значениям адреса. Указатель стека - это точка, в которой следующий вызов push (или вызов) поместит следующее значение. Эта операция эквивалентна оператору C / C ++:

 // push eax
 --*esp = eax
 // pop eax
 eax = *esp++;

 // a function call, in this case, the caller must clean up the function parameters
 move eax,some value
 push eax
 call some address  // this pushes the next value of the instruction pointer onto the
                    // stack and changes the instruction pointer to "some address"
 add esp,4 // remove eax from the stack

 // a function
 push ebp // save the old stack frame
 move ebp, esp
 ... // do stuff
 pop ebp  // restore the old stack frame
 ret

Базовый указатель находится в верхней части текущего кадра. ebp обычно указывает на ваш обратный адрес. ebp + 4 указывает на первый параметр вашей функции (или значение this метода класса). ebp-4 указывает на первую локальную переменную вашей функции, обычно на старое значение ebp, поэтому вы можете восстановить указатель предыдущего кадра.

6
ответ дан 23 November 2019 в 04:26
поделиться

esp - это, как вы говорите, вершина стека.

ebp обычно устанавливается на esp в начале функция. Доступ к параметрам функции и локальным переменным осуществляется путем добавления и вычитания, соответственно, постоянного смещения из ebp . Все соглашения о вызовах x86 определяют ebp как сохраняемые при вызовах функций. Сама ebp фактически указывает на базовый указатель предыдущего кадра, что позволяет перемещаться по стеку в отладчике и просматривать локальные переменные других кадров для работы.

Большинство прологов функций выглядят примерно так: Он описывает нечто совершенно иное, если кому-то интересно :)

Да, указатель стека указывает на вершину стека (будь то первое пустое место стека или последнее полное, в котором я не уверен). Базовый указатель указывает на место в памяти выполняемой инструкции. Это на уровне кодов операций - самой простой инструкции, которую вы можете получить на компьютере. Каждый код операции и его параметры хранятся в ячейке памяти. Одна строка C, C ++ или C # может быть преобразована в один код операции или последовательность из двух или более в зависимости от того, насколько она сложна. Они последовательно записываются в память программы и выполняются. В нормальных условиях базовый указатель увеличивается на одну инструкцию. Для программного управления (GOTO, IF и т. Д.) Его можно увеличивать несколько раз или просто заменять следующим адресом памяти.

В этом контексте функции хранятся в памяти программ по определенному адресу. Когда функция вызывается, определенная информация помещается в стек, что позволяет программе найти ее место, откуда функция была вызвана, а также параметры функции, затем адрес функции в памяти программы помещается в базовый указатель. В следующем тактовом цикле компьютер начинает выполнять инструкции с этого адреса памяти. Затем в какой-то момент он ВОЗВРАЩАЕТСЯ в ячейку памяти ПОСЛЕ инструкции, которая вызвала функцию, и продолжит работу оттуда.

определенная информация помещается в стек, что позволяет программе найти, откуда она была вызвана, а также параметры функции, затем адрес функции в памяти программы помещается в базовый указатель. В следующем тактовом цикле компьютер начинает выполнять инструкции с этого адреса памяти. Затем в какой-то момент он ВОЗВРАЩАЕТСЯ в ячейку памяти ПОСЛЕ инструкции, которая вызвала функцию, и продолжит работу оттуда.

определенная информация помещается в стек, что позволяет программе найти, откуда она была вызвана, а также параметры функции, затем адрес функции в памяти программы помещается в базовый указатель. В следующем тактовом цикле компьютер начинает выполнять инструкции с этого адреса памяти. Затем в какой-то момент он ВОЗВРАЩАЕТСЯ в ячейку памяти ПОСЛЕ инструкции, которая вызвала функцию, и продолжит работу оттуда.

-3
ответ дан 23 November 2019 в 04:26
поделиться

esp означает "Extended Stack Pointer".....ebp означает "Something Base Pointer".... и eip означает "Something Instruction Pointer"....... Указатель стека указывает на адрес смещения сегмента стека. Указатель базы указывает на адрес смещения дополнительного сегмента. Указатель инструкции указывает на адрес смещения сегмента кода. Теперь о сегментах... они представляют собой небольшие 64 КБ области памяти процессора..... Этот процесс известен как сегментация памяти. Надеюсь, этот пост был полезен.

-5
ответ дан 23 November 2019 в 04:26
поделиться