Разное

Ассемблер esp: Программирование на языке ассемблера

c — Выравнивание значения в ESP на 16 байт

Вопрос задан

Изменён 6 лет 9 месяцев назад

Просмотрен 1k раза

Дизассемблировал такую простую программу:

push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
mov eax, offset aHelloWorld ; "hello, world\n"

Строка and esp, 0FFFFFFF0h мне всегда мозолила глаза, а ее смысл в книгах по реверсу не объясняется. Пишут, что это выравнивание значения в ESP по 16-байтной границе, но «выравнивание», «обнуление первых четырех бит» и «16 байт» у меня никак не складываются в завершенную идею. Что здесь происходит? Для чего это? Почему для выравнивания на 16 байт надо обнулить 4 бита?

Выравнивание я понимаю как заполнение кусков памяти до кратности какому-то числу.

k) выравнивания числа x рассчитываются следующим образом:

x & ~(n - 1) // вниз, до ближайшего меньшего числа кратного n
(x + n - 1) & ~(n - 1) // вверх, до ближайшего большего числа кратного n

Неиспользуемые куски памяти называются padding и строго говоря к выравниванию отношения не имеет. При этом они могут быть ничем не заполнены (dup alignment (?)).

Поскольку стек растет вниз, то его выравниваниют снизу, т.е. при помощи

and esp, ~0xf

Стек «растет» в сторону уменьшения адресов:

То есть получив ESP и желая его выровнять, отсекаются младшие 4 бита (при этом ESP станет указывать на участок памяти, находящийся через некоторое количество байт от «прошлого» ESP). Тогда да, в стеке могут образовываться «дырки». Так сказано в документации, что ESP выравнен по границе 16 бит. Насчёт целесообразности — вопрос к разработчикам, но они утверждают, что это увеличивает производительность.

3

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

Рекомендации по написанию кода Prolog-Epilog

Twitter LinkedIn Facebook Адрес электронной почты

  • Статья
  • Чтение занимает 2 мин

Блок, относящийся только к системам Microsoft

Прежде чем писать собственные последовательности кода пролога и эпилога, важно понимать, как размещается кадр стека. Также полезно знать, как использовать __LOCAL_SIZE символ.

Макет кадра стека

В данном примере показан стандартный код пролога, который может присутствовать в 32-разрядной функции.

push        ebp                ; Save ebp
mov         ebp, esp           ; Set stack frame pointer
sub         esp, localbytes    ; Allocate space for locals
push        <registers>        ; Save registers

Переменная localbytes представляет число байтов, которые требуются в стеке для локальных переменных, а переменная <registers> — это заполнитель, представляющий список сохраняемых в стеке регистров. После проталкивания регистров можно разместить в стеке все другие необходимые данные. Ниже приведен соответствующий код эпилога.

pop         <registers>   ; Restore registers
mov         esp, ebp      ; Restore stack pointer
pop         ebp           ; Restore ebp
ret                       ; Return from function

Стек всегда расширяется в направлении вниз (от старших адресов памяти к младшим). Указатель базы (ebp

) указывает на помещенное в стек значение ebp. Область локальных переменных начинается с адреса ebp-4. Для доступа к локальным переменным необходимо вычислить смещение от ebp путем вычитания соответствующего значения из ebp.

__LOCAL_SIZE

Компилятор предоставляет символ для __LOCAL_SIZEиспользования в блоке встроенного ассемблера кода пролога функции. Этот символ служит для выделения пространства локальным переменным в кадре стека пользовательского кода пролога.

Компилятор определяет значение __LOCAL_SIZE. Это значение представляет общее количество байтов всех определяемых пользователем локальных переменных и временных переменных, создаваемых компилятором. __LOCAL_SIZE может использоваться только в качестве немедленного операнда; Его нельзя использовать в выражении. Значение этого символа не следует изменять и переопределять. Пример:

mov        eax, __LOCAL_SIZE           ;Immediate operand--Okay
mov        eax, [ebp - __LOCAL_SIZE]   ;Error

В следующем примере голой функции, содержащей пользовательские последовательности пролога и эпилога, используется __LOCAL_SIZE символ в последовательности пролога:

// the__local_size_symbol. cpp
// processor: x86
__declspec ( naked ) int main() {
   int i;
   int j;
   __asm {      /* prolog */
      push   ebp
      mov      ebp, esp
      sub      esp, __LOCAL_SIZE
      }
   /* Function body */
   __asm {   /* epilog */
      mov      esp, ebp
      pop      ebp
      ret
      }
}

Завершение блока, относящегося только к системам Майкрософт

См. также

Вызовы функции Naked

Сборка

— что такое регистры ESP и EBP?

спросил

Изменено 1 месяц назад

Просмотрено 126 тысяч раз

Я обнаружил, что регистр ESP является текущим указателем стека, а EBP — базовым указателем для текущего фрейма стека. Однако я не понимаю этих определений (я только начинаю учиться программировать на ассемблере).

Насколько я понимаю, ESP указывает на сам стек, а EBP указывает на то, что находится на вершине стека 1 . Но это только мои догадки и они скорее всего неверны. В противном случае, что бы означало утверждение, подобное следующему?

 МОВ ЭБП, ЭСП
 

Сноска 1: Примечание редактора: Да, это неверно. В стандартной терминологии «вершина стека» — это точка, на которую указывает ESP, даже если это самый нижний адрес в кадре стека. По аналогии со структурой данных стека, которая растет вверх, хотя стек вызовов на x86 (как и в большинстве ISA) растет вниз.

  • сборка
  • x86
  • стек вызовов
  • стек-фрейм

1

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

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

3

Обычно EBP используется для резервного копирования ESP, поэтому, если ESP изменен кодом в функции, все, что требуется для восстановления ESP, — это mov esp, ebp . Поскольку EBP обычно остается неизменным в коде функции, его можно использовать для доступа к переданным параметрам или локальным переменным без необходимости корректировки смещений.

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

Обратите внимание, что некоторые компиляторы имеют параметр «опустить указатели кадров», в этом случае EBP не используется для сохранения ESP или в качестве указателя кадра стека, что позволяет использовать EBP для переменной. Компилятор отслеживает ESP, и все локальные смещения являются смещениями от текущего значения ESP.

EBP и ESP — пережитки эпохи, когда компиляторы, например, не иметь статический анализ, чтобы определить, сколько байтов стека необходимо для вызова функции. Также стек должен был динамически увеличиваться и уменьшаться во время выполнения функции, прерывания позволяли бы уничтожить весь стек от 0 до SP, а спагетти-код был стандартом де-факто. На самом деле прерывания (и передача параметров только через регистры) были разработанным методом для вызова функций ядра.

В этом окружении один нуждается в , чтобы иметь фиксированную точку стека, где всегда находится адрес возврата вызывающему, локальные переменные и аргументы функции. Таким образом, регистр п.н. был оправдан. В этой архитектуре bp было разрешено индексировать ([bp — 300h]), а sp — нет. Коды операций/инструкций, которые можно было интерпретировать как mov ax, [sp + 1111h] , были повторно использованы для других целей.

В версии 386+ и с введением буквы «Е» ESP приобрело свойство смещения. В это время EBP был освобожден от единственной цели, так как esp мог справиться с обеими задачами.

Обратите внимание, что даже сейчас EBP указывает на память через стек сегмент (SS), точно так же, как ESP . Другие режимы адресации (без ESP/EBP в качестве основы) по умолчанию относятся к сегменту DS. (абсолютный, DI, SI и/или BX в 16-битном режиме и в 32-битном режиме адресации любой регистр может быть базовым в режиме адресации).

2

Регистр ESP является указателем стека для системного стека. Он редко изменяется непосредственно программой, но изменяется когда данные помещаются в стек или извлекаются из стека. Одно из применений стека — вызовы процедур. адрес инструкций, следующих за инструкцией вызова процедуры, хранится в стеке. указатели регистра EBP на базу. обычно единственный элемент данных, к которому осуществляется доступ в стеке, — это тот, который находится на вершине стека. Хотя регистр EBP часто используется для обозначения фиксированной точки в стеке, отличной от вершины стека, например, такими данными являются параметры. Они смещаются от вершины стека EBP к базовому указателю после адреса возврата. Итак, вы увидите что-то вроде EBP+0x8, EBP+0xC, это параметры как в 1 и 2 соответственно.

Понимание стека очень важно при программировании на языке ассемблера, поскольку это может повлиять на соглашения о вызовах, которые вы будете использовать независимо от типа. Например, даже cdecl или __stdcall тоже зависят от регистров ESP и EBP, а другие тоже каким-то образом зависят от каких-то регистров и стека.

1

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Представительная ассамблея NEA удостоена награды ESP 2019 года

Автор: Тим Уокер 6 ИЮЛЯ 2019 ГОДА.

Мэтью Пауэлл, специалист года по поддержке образования 2019 года, вышел на сцену представительной ассамблеи NEA в субботу. Представляя его почти 7000 делегатам, собравшимся в конференц-центре Джорджа Э. Брауна в Хьюстоне, президент NEA Лили Эскельсен Гарсия похвалила Пауэлла за его «приверженность общественному образованию и нашим студентам».

«Технически у него есть должность надзирателя», — добавил Эскельсен Гарсия. «Но это только одна из многих шляп, которые носит этот талантливый человек».

Помимо своей работы надзирателем, Пауэлл также работает ночным сторожем и подменяет водителя автобуса, когда округу нужны подменные водители. Он работает в Центральной начальной школе округа Грейвс в Мэйфилде, штат Кентукки.

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

«В мой «класс» входят все 538 учеников моей школы, — сказал Пауэлл делегатам. «Мой класс находится в автобусе, в столовой, на игровой площадке, в холлах, у пруда с рыбками кои и во многих других местах вокруг школы».

В своей речи Пауэлл уделил внимание четырем педагогам — учителю, водителю автобуса, «обедительнице» и школьному сторожу, — которые повлияли на его взросление и помогли ему стать педагогом, которым он является сегодня.

«На самом деле эти педагоги создали атмосферу, в которой я чувствовал поддержку, питание и безопасность. Они создали среду, в которой я мог получать удовольствие и развиваться в школе. разница в моей жизни», — сказал Пауэлл.

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

Специалист года по поддержке образования 2019 года Мэтью Пауэлл @espunite делится своими 5 убеждениями, которые помогут всем его ученикам добиться успеха 👇 #NEARA19 pic.twitter.com/vAkICaiqtb

— Департамент качества NEA ESP (@NEArESPect) 6 июля 2019 г.

Делиться этой историей с делегатами не планировалось как «путешествие в прошлое», — сказал Пауэлл.

«Я хочу напомнить всем нам о том влиянии и силе, которые мы имеем в жизни наших учеников, в наших школах и в наших сообществах. Эта сила доступна каждому из нас, каждый день, в больших масштабах. и, казалось бы, в мелочах», — сказал он под аплодисменты делегатов.

Пауэлл, преданный политический активист государственных школ в Кентукки, упомянул о мощном союзе между учителями и ESP, разжигающем движение #RedForEd по всей стране.

«У ESP есть ценный опыт и знания, которые должны информировать наши школы о решениях, принимаемых в наших школах», — сказал Пауэлл. «Мы хорошо знаем наших студентов, и многие из нас живут в сообществе, где мы работаем … Мы заслуживаем места за каждым столом, где принимаются политики и решения, которые влияют на наших работ, наших студентов и наших сообществ, которые мы служим».

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

«Он установил первое в истории федеральное признание экстрасенсов», — сказал Пауэлл делегатам. «Это была победа, которая была бы невозможна без педагогов, которые обратились к членам Конгресса и поделились своим мнением. Это было удивительное достижение, но оно давно назрело».

Цитируя Хелен Келлер, Пауэлл призвал делегатов помнить, что «в одиночку мы можем сделать так мало; вместе мы можем сделать так много».

«Мы должны продолжать использовать наш коллективный голос и рассказывать наши истории, чтобы возвышать нашу профессию и требовать того, что нам нужно для наших студентов, — сказал Пауэлл в заключение.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *