В этой статье мы с вами познакомимся с основными понятиями, которые связаны со стеком в Assembler, напишем небольшую программу, изучим несколько новых команд.
Общая информация
Итак, что же такое стек: если коротко, то стек — область памяти на ядре процессора, там хранятся адреса. По своей сути, это абстрактный тип данных. В понимании он довольно прост и следующая иллюстрация отображает принцип работы стека:
Принцип работы можно выразить простыми словами: первым пришел — последним вышел, и наоборот: последним пришел — первым вышел. Это полностью описывает работу стека в 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, если у вас остались вопросы, то пишите в комментариях.
Скачать исходники
Будьте первым, кто оставит комментарий