Сборка практикуется в понимании того, что происходит с push-командой

#assembly #x86 #stack #cpu-registers

#сборка #x86 #стек #cpu-регистры

Вопрос:

В нашем курсе есть практика использования assembly, которая выглядит следующим образом.
Что сохраняется в регистре EAX после этого кода?

 mov eax, 10
push eax
push 20
mov ecx, eax
pop eax
  

Итак, из того, что я понял, первая строка означает, что 10 помещается в EAX, а во второй строке EAX помещается в стек.

Но что это значит? Удаляется ли содержимое eax?
Если 20 также помещается в стек, то стек равен 10 и 20?

Будет ли EAX регистрироваться после кода примерно как 10, 10, 20 или что-то еще и как оно отформатировано?

Комментарии:

1. push просто дублирует содержимое, реплицируя его в стек; нет никаких изменений в источнике (просто записывается память и корректируется указатель стека). pop также не уничтожает исходную ячейку памяти, но поскольку указатель стека настроен, выделенная ячейка памяти теперь находится ниже указателя стека и поэтому считается свободной для перезаписи.

2. felixcloutier.com/x86/push документирует именно то, что происходит при push выполнении инструкции; ни больше, ни меньше. Каждая инструкция просто документирует свое влияние на состояние архитектуры. Выполните эту последовательность в отладчике одним шагом, если вы не уверены, что произойдет от моделирования в вашей голове. (И, кстати, инструкции обычно оставляют регистр или ячейку памяти неизмененными после ее чтения, если только это не явная часть инструкции, например xchg .)

Ответ №1:

Давайте пройдемся по этому шаг за шагом:

 mov eax, 10    ; This assigns the value 10 to the register EAX
push eax       ; This puts the value of EAX onto the stack (a LIFO structure)
push 20        ; This puts the DWORD value 20 onto the stack
mov ecx, eax   ; This moves the value of the register EAX to the register ECX - the left hand side is the destination in x86 assembly with intel syntax
pop eax        ; This puts the top value of the stack into EAX and decreases the stackpointer to now point to the preceding item
  

Последняя инструкция требует некоторой дополнительной информации. Я упоминал, что стек представляет собой структуру данных LIFO. Это означает «Последний вход-первый выход«.

Поэтому значение EAX(= 10) сначала помещается в стек. На следующем шаге значение 20 помещается в стек. mov ecx, eax Инструкция не имеет смысла для этой задачи и может быть проигнорирована. Теперь, с pop eax помощью, последний элемент (помните LIFO), который был помещен в стек, извлекается и помещается в регистр EAX.

Следовательно, окончательный ответ — EAX = 20.

Комментарии:

1. Хорошо, что левая сторона является местом назначения для обычного / собственного синтаксиса или синтаксиса Intel для x86, но правая сторона синтаксиса AT amp; T является местом назначения (левая сторона не является местом назначения для всех сборок x86). Первая инструкция является подсказкой здесь, что это, вероятно, синтаксис intel, и поэтому ecx получает копию eax. К счастью, эта инструкция не имеет отношения к результату, поэтому стиль синтаксиса не влияет на этот вопрос. Здесь уместны только две инструкции, и у них нет проблем с intel и AT amp; T.

2. @old_timer: я добавил уведомление о том, что рассматриваемая часть использует синтаксис Intel . В противном случае, если бы код использовал синтаксис AT amp; T, он был бы заполнен % символами, поэтому любой мог легко заметить это.