Возможно, Вы спрашиваете о хранении таких вещей, идущих...
, Конечно, Вы вызовете полное сканирование таблицы на предмет запросов и если таблица, содержащая очки, которым нужно соответствовать (агрегирования), является большой, Вы могли бы хотеть лучшее решение для выполнения, можно составить вторичную таблицу и использовать правила, такой как on insert
- Вы могли бы изучить ее.
Не все механизмы RDBMS имеют правила, хотя!
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
и т. д.) ebp
ESP - это текущий указатель стека, который будет изменяться каждый раз, когда слово или адрес помещается в / из стека. EBP - более удобный способ для компилятора отслеживать параметры функции и локальные переменные, чем использование ESP напрямую.
Как правило (и это может варьироваться от компилятора к компилятору), все аргументы вызываемой функции являются помещаются в стек вызывающей функцией (обычно в порядке, обратном их объявлению в прототипе функции, но это может быть разным). Затем вызывается функция, которая помещает адрес возврата (EIP) в стек.
При входе в функцию старое значение EBP помещается в стек, а EBP устанавливается на значение ESP. Затем ESP уменьшается (поскольку стек увеличивается вниз в памяти), чтобы выделить место для функции ' s локальные переменные и временные. С этого момента во время выполнения функции аргументы функции располагаются в стеке с положительными смещениями от EBP (поскольку они были помещены до вызова функции), а локальные переменные располагаются с отрицательными смещениями от EBP. (потому что они были размещены в стеке после входа в функцию). Вот почему EBP называется указателем кадра , потому что он указывает на центр кадра вызова функции .
При выходе все, что нужно сделать функции, - это установить ESP на значение EBP (которое освобождает локальные переменные из стека и выставляет запись EBP наверху стека), затем выталкивает старое значение EBP из стека, а затем функция возвращает (выталкивая адрес возврата в EIP) .
После возврата к вызывающей функции, Затем он может увеличивать ESP, чтобы удалить аргументы функции, которые он поместил в стек непосредственно перед вызовом другой функции. В этот момент стек вернулся в то же состояние, в котором он находился до вызова вызываемой функции.
Вы правы. Указатель стека указывает на верхний элемент стека, а базовый указатель указывает на «предыдущую» вершину стека до вызова функции.
Когда вы вызываете функцию, любая локальная переменная будет будут сохранены в стеке, и указатель стека будет увеличиваться. Когда вы возвращаетесь из функции, все локальные переменные в стеке выходят из области видимости. Вы делаете это, устанавливая указатель стека обратно на базовый указатель (который был «предыдущей» вершиной перед вызовом функции).
Распределение памяти таким способом очень , очень быстро и эффективно.
РЕДАКТИРОВАТЬ: Для лучшего описания см. Дизассемблирование / Функции 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,
Давно я не занимался программированием на ассемблере, но эта ссылка может быть полезна ...
Процессор имеет набор регистров, которые используются для хранения данные. Некоторые из них являются прямыми значениями, а другие указывают на область в ОЗУ. Регистры, как правило, используются для определенных действий, и каждый операнд в сборке потребует определенного количества данных в определенных регистрах.
Указатель стека в основном используется, когда вы вызываете другие процедуры. В современных компиляторах сначала в стек будет выгружена пачка данных, за которой следует адрес возврата, чтобы система знала, куда вернуться, как только ей будет приказано вернуться. Указатель стека будет указывать на следующее место, где новые данные могут быть помещены в стек, где они будут оставаться до тех пор, пока не будут возвращены обратно.
Базовые регистры или сегментные регистры просто указывают на адресное пространство большого объема данных. В сочетании со вторым регистром базовый указатель разделит память на огромные блоки, а второй регистр будет указывать на элемент в этом блоке. Базовые указатели для этого указывают на базу блоков данных.
Имейте в виду, что сборка очень зависит от процессора. Страница, на которую я указал, предоставляет информацию о различных типах процессоров.
Прежде всего, указатель стека указывает на нижнюю часть стека, поскольку стеки 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, поэтому вы можете восстановить указатель предыдущего кадра.
esp
- это, как вы говорите, вершина стека.
ebp
обычно устанавливается на esp
в начале функция. Доступ к параметрам функции и локальным переменным осуществляется путем добавления и вычитания, соответственно, постоянного смещения из ebp
. Все соглашения о вызовах x86 определяют ebp
как сохраняемые при вызовах функций. Сама ebp
фактически указывает на базовый указатель предыдущего кадра, что позволяет перемещаться по стеку в отладчике и просматривать локальные переменные других кадров для работы.
Большинство прологов функций выглядят примерно так: Он описывает нечто совершенно иное, если кому-то интересно :)
Да, указатель стека указывает на вершину стека (будь то первое пустое место стека или последнее полное, в котором я не уверен). Базовый указатель указывает на место в памяти выполняемой инструкции. Это на уровне кодов операций - самой простой инструкции, которую вы можете получить на компьютере. Каждый код операции и его параметры хранятся в ячейке памяти. Одна строка C, C ++ или C # может быть преобразована в один код операции или последовательность из двух или более в зависимости от того, насколько она сложна. Они последовательно записываются в память программы и выполняются. В нормальных условиях базовый указатель увеличивается на одну инструкцию. Для программного управления (GOTO, IF и т. Д.) Его можно увеличивать несколько раз или просто заменять следующим адресом памяти.
В этом контексте функции хранятся в памяти программ по определенному адресу. Когда функция вызывается, определенная информация помещается в стек, что позволяет программе найти ее место, откуда функция была вызвана, а также параметры функции, затем адрес функции в памяти программы помещается в базовый указатель. В следующем тактовом цикле компьютер начинает выполнять инструкции с этого адреса памяти. Затем в какой-то момент он ВОЗВРАЩАЕТСЯ в ячейку памяти ПОСЛЕ инструкции, которая вызвала функцию, и продолжит работу оттуда.
определенная информация помещается в стек, что позволяет программе найти, откуда она была вызвана, а также параметры функции, затем адрес функции в памяти программы помещается в базовый указатель. В следующем тактовом цикле компьютер начинает выполнять инструкции с этого адреса памяти. Затем в какой-то момент он ВОЗВРАЩАЕТСЯ в ячейку памяти ПОСЛЕ инструкции, которая вызвала функцию, и продолжит работу оттуда. определенная информация помещается в стек, что позволяет программе найти, откуда она была вызвана, а также параметры функции, затем адрес функции в памяти программы помещается в базовый указатель. В следующем тактовом цикле компьютер начинает выполнять инструкции с этого адреса памяти. Затем в какой-то момент он ВОЗВРАЩАЕТСЯ в ячейку памяти ПОСЛЕ инструкции, которая вызвала функцию, и продолжит работу оттуда.esp означает "Extended Stack Pointer".....ebp означает "Something Base Pointer".... и eip означает "Something Instruction Pointer"....... Указатель стека указывает на адрес смещения сегмента стека. Указатель базы указывает на адрес смещения дополнительного сегмента. Указатель инструкции указывает на адрес смещения сегмента кода. Теперь о сегментах... они представляют собой небольшие 64 КБ области памяти процессора..... Этот процесс известен как сегментация памяти. Надеюсь, этот пост был полезен.