SiteSearch
logo

Документация и статьи по Ассемблеру, Reversing:

"Тем, кто охвачен враждою и страстью,
Нелегко постичь это ученье.
Страсти предавшись, тьмою объятые,
Они не поймут того, что тонко,
Что глубоко и трудно для постиженья,
Что против теченья их мысли".


Винайя-питака.


Значит у нас три основных сегмента, сегменты кода, данных и стека. По сути сегмент-
это выделенный кусочек памяти размером в 64 кб, однако, при трансляции, часто
(почти всегда если специально не укзывать обратное) все эти три сегмента располагаются
в одном сегменте, т.к. не имеет смысла тратить память и  процессорное время на
то что может быть в одном сегменте. По сути для программиста это не имеет особого
значения, но может в будущем пригодится. К стати, открыв программу в hex редакторе
типа HVIEW ты не увидиш
никакой разницы между сегментами кода, стека и данных.Разве что визуально заметиш
свои команды.
Единственные границы - это границы которые определяются содержанием регистров
cs,ds,ss, т.е. адресные границы.
 Что -же такое стек, и для чего он нужен.
По сути стек- лишь форма организации памяти. Это означает, что заранее известно,
чтo всегда еденицой данных в стеке является слово. т.е. если мы отправили в стек
3 бита к примеру, эти три бита заполнятся, а остальное будет забито нуликами.
Чаще всего стек используется для передачи параметров функциям (процедурам, это
на асме одно и то-же), а в языках высокого уровня, еще и для хранения переменных,
 массивов и т.п.. А так-же для хранения локальных переменных (процедур, функций),
о чем будет упомянуто особо.
Кстати, статические данные всегда хранятся в массиве данных.
Значит на адрес начала стека указывает регистр SS, на вершину(top) указывает
регистр SP. Что значит вершина стека: это то слово которое было последним добавлено
в стек. Для работы со стеком определены несколько команд, вот две основные команды-
PUSH и POP
Команда PUSH помещает в стек слово. Пример:
Push ax ;помещает содержимое регистра ax в стек
push 77 ; помещает число 77 в стек.

если потом сделать pop ax, в регистре ax будет число 0077.
Т.есть pop вытаскивает из стека последнее слово, и помещает его в регистр являющийся
операндом этой команды. В данном случае – в ах.

Очень кстати удобно, так как часто бывает что нехватает регистров, или к примеру
 во время работы процедуры изменяются значения нужных нам регистров, а нам надо
из сохранить. Example:
error proc
push dx
push ax

mov ah,09h
mov dx,offset err
int 21h
pop ax
pop dx
ret    ;возврат из процедуры

err db 'ERROR!!!$'
error endp

теперь мы можем вызывать эту процедуру из любой точки программы, не боясь, что
нужные нам значения регистров потеряются.
Так-же со стеком работают команды CALL и RET. CALL - вызов процедуры, она кладет
в стек текущий адрес, и делает jmp на метку процедуры. RET же берет из стека
адрес и переходит на следующую команду после call.
Example:

data segment
db 'in main program',13,10,'$'
perem dw 1 dup(0)
db 'in procedure',13,10,'$'
data ends

stk segment stack
       db 30 dup(0)
stk ends

codseg segment
ASSUME CS:CODSEG,SS:STK,DS:DATA
begin:
       mov ax,data
       mov ds,ax
       mov ax,stk
       mov ss,ax

       mov ah,09h
       mov dx,0

       call func

       int 21h

       mov ah,4ch
       int 21h

func proc
       push ax
       push dx

       mov ax,10
       add ax,44
       mov perem,ax
       mov ah,09h
       mov dx,offset perem
       int 21h
       pop dx
       pop ax

       ret
func endp

codseg ends
 end begin    

Система работы со стеком: наиболее простой аналогией является стопка блинов-FILO
(First In Last Out первым пришел последним ушел), Блин который мы положили последним,
первым мы и снимем. А самый первый блин будет съеден последним :)

 Вот, почему порядок вытаскивания из стека должен быть противоположен порядку
“складывания” в него. Немного похоже на паскальские скобки begin...end,
каждому begin должен соответствовать свой end. Короче:

push ax
push cx
push bx

pop bx
pop cx
pop ax
чтобы получить правильные начальные значения регистров.

Ну и напоследок небольшая програмка, иллюстрирующая свойства стека:

title stack

data segment
       db 10 dup(0)
       db 'BCE PAbOTAET!!!',13,10,'$'
data ends

stackseg segment stack
       db 40 dup(1)
stackseg ends

codesegm segment
ASSUME CS:codesegm,DS:data,SS:stackseg
begin:
       mov ax,data
       mov ds,ax

       mov ax,stackseg
       mov ss,ax

loo:

       mov ax,77h
       push ax
       mov bp,sp
       cmp [bp],77h
       jl loo
       jg loo

       mov dx,10
       mov ah,09h
       int 21h

       mov ah,01h
       int 21h

       mov ah,4ch
       int 21h
codesegm ends
       end begin

Думаю, что тут даже комментарии излишни, все просто.


Регистр флагов.
Используя команду cmp, а так-же условные jmp-ы (jz,jnz,jl и пр.) вы наверно могли
задуматься, а откуда процессор узнает, например что 4=4 (cmp), когда выполняет
команду jz. Для этих целей существует регистр флагов, в котором каждый бит выполняет
какую-то функцию.
15-12  биты зарезервированы
11     OF (Overflow Flag) флаг переполнения. Поднимается(т.е. устанавливается в
1
когда результат вычисления превышает допустимые размеры.
10     DF флаг направления
9      IF (Interrupt Flag) флаг прерывания. Если он сброшен(установлен в 0) то процессор
не реагирует на внешние сигналы(прерывания).
8      TF (Trace Flag) флаг трассировки. Если поднят, то после выполнения каждой операции
обращается к спец. прерыванию. Используется в отладчиках.
7      SF флаг знака. Используется при работе со знаковыми числами.
6      ZF (Zero Flag) флаг нуля. Равен 1 если результат действия(сравнения к примеру)
является true, и 0 если false.
5      зарезервирован
4      AF вспомогательный флаг переноса.
3      зарезервирован
2      PF флаг четности.
1      зарезервирован
0      CF флаг переноса. одно из применений – индикация того, что при выполнении
ДОС-функции произошла ошибка.

Вот к примеру, если при сравнении cmp ax,4 ах равен 4 то поднимается ZF, и если
 далее сделать JZ (Jump If Zero Прыг если Нуль, т.е. перейти, если флаг нуля
поднят) то будет произведен jump, а если не равен, то он не будет произведен.
 Короче все условные jump-ы используют регистр флагов.
Кроме jump-ов, так-же и другие команды, смотрим которые в приложении.


ведущий рассылку Skif_Q.
skif_q@mail.ru
http://ass3mbler.narod.ru/ – тут все выпуски рассылки, программы, остальное.

[Главная] [Документация] [Теория] [Практика] [Рассылки] [Книги] [Исходники] [Reversing] [Друзья] [Архив] [Диски] [Новости]

Посещаемость сайта такова:
На деревню дедушке

Hosted by uCoz

Rambler's Top100
РЕГИСТРАТУРА.РУ: бесплатная автоматическая регистрация в каталогах ссылок и поисковых машинах, проведение рекламных кампаний в Интернете, привлечение на сайт целевых посетителей.

Hosted by uCoz