Skip to content

Стек и косвенная адресация

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

Общая информация

Итак, что же такое стек: если коротко, то стек — область памяти на ядре процессора, там хранятся адреса. По своей сути, это абстрактный тип данных. В понимании он довольно прост и следующая иллюстрация отображает принцип работы стека:

Assembler-3

Принцип работы можно выразить простыми словами: первым пришел — последним вышел, и наоборот: последним пришел — первым вышел. Это полностью описывает работу стека в Assembler.

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

Стек в Assembler

Для основ, нам необходимо знать 2 новые команды:

  • push — поместить в стек
  • pop — вытащить из стека

Также нам понадобится такая конструкция :
[esp] — это указатель на вершину стека, как раз с ней мы и будем работать.

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

.386
.model flat,stdcall
.data
.code

Уже знакомые строки, которые необходимо прописывать.
Перейдем к разделу кода:

start:
mov ax, 2211h
mov ecx, 66554433h
push ax
push ecx
pop ax
pop ecx

Сначала в регистры ax и ecx помещаем значения(h означает шестнадцатеричную систему исчисления,и по сути никак не относится к числу). Заметьте, что в регистр ax, содержащий максимум 2 байта, можно поместить только 4 цифры, а в регистр ecx, содержащий 4 байта, только 8.

Затем с помощью команды push, помещаем в стек значения регистров ax и ecx соответственно, то есть сначала мы положили 2 байта, а затем еще 4 байта. Таким образом сейчас на вершине стека лежит то число из 8 знаков.

Далее, с помощью команды pop, вынимаем значения в регистры ax и ecx соответственно. Только заметьте, так как регистр ax, как мы уже сказали, может содержать 4 цифры(или правильнее сказать 2 байта), то в него запишется только 2 байта. Это означает что, то значение из 8 цифр, которое лежит на вершине, будет разделено пополам, а последняя половинка запишется в регистр ax(по принципу последним пришел — первым вышел). То есть в регистр ax запишется 4433h. И после этого в регистр ecx запишется 4 байта, а именно, то что останется: ecx = 22116655h.
Итак, поменяли значения регистра, а теперь изучим косвенную адресацию:

Косвенная адресация

mov ecx,[esp-6]
mov ax,[esp-2]
ret
end start

Для понимания нужна полная сосредоточенность: итак, после выполнения команд pop(которая вытаскивает значения, но не удаляет его), вершина стека сместилась относительно наших значений сначала на 2 байта, а затем еще на 4, в общем на 6 байт. Так вот, с помощью косвенной адресации [esp-2] и [esp-6] мы можем обратится как раз к тем значениям: в итоге мы в ecx поместим значение, которое было в самом начале: 66554433h, в регистр ax: 2211h(просто вернули первоначальные значения).

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

На этом мы закончим с изучением темы стек в Assembler, если у вас остались вопросы, то пишите в комментариях.

Скачать исходники

Опубликовано вAssembler

Будьте первым, кто оставит комментарий

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