Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
assmblr.docx
Скачиваний:
218
Добавлен:
16.02.2016
Размер:
366.71 Кб
Скачать

2.3. Взаимодействие ассемблерных программ с памятью

Разобраться с вопросом взаимодействия ассемблерных программ с памятью нам поможет следующая программа.

.386

.model flat, stdcall

.data

data_8 db -3

data_16 dw ?

.code

start:

mov al, data_8

sub ah, ah

dec ah

mov data_16, ax

ret

end start

В программе использована директива .data, указывающая процессору, что следом за ней идут данные — числа, символы, словом, все то, что нельзя считать командами процессора. Ассемблер будет считать данными все, что расположено в исходном тексте программы до директивы .code.

Запись data_8 db -3 означает, что в области памяти под именем data_8 хранится байт -3. Запись data_16 dw ? выделяет память для двух идущих подряд байтов (слова), знак вопроса показывает, что значение байтов заранее не определено.

Инструкция mov al, data_8 берет из памяти байт, помеченный как data_8, и записывает его содержимое в регистр al. При этом содержимое байта data_8 не страдает, он как бы размножается, ведь после выполнения инструкции число -3 оказывается не только в памяти, но и в регистре al.

Инструкция sub ah, ah посылает разность ah-ah в регистр ah. Каким бы ни было содержимое ah, там после такой операции окажется 0. Наконец, инструкция dec ah уменьшает содержимое ah на единицу. А поскольку там до этого оказался 0, то в результате получится 0 - 1 = -1 или 0FFh в шестнадцатеричном представлении.

Инструкция dec, обращающая все биты ah в единицу, расширяет знак числа -3, попавшего в al. После нее число -3 переселяется в регистр ах, откуда пересылается инструкцией mov data_16, ax в область памяти data_16, состоящую из двух идущих подряд байтов.

Чтобы «почувствовать» адреса памяти, полезно увидеть результаты работы программы в окне отладчика OllyDbg.

В левом верхнем углу видны адреса памяти, занимаемой командами процессора. Первая инструкция располагается в памяти, начиная с адреса 00401000, и занимает 5 байт. Вторая инструкция sub ah, ah умещается в двух байтах с адресами 00401005, 00401006. Наконец, последняя инструкция ret занимает всего один байт и находится по адресу 0040100f.

Несмотря на то, что область данных помещена в отладчике раньше команд, имеет большие адреса, видные в левом нижнем окне отладчика. Байт data_8 имеет адрес 0040200 и хранит число -3 или fd в шестнадцатеричном виде. Следующие два байта помечены в листинге словом data_16 и должны хранить FFFD – число -3, записанное в дополнительном коде. Но отладчик показывает, что первым идет байт FD (его адрес 0040201)), а следом уже байт FF (его адрес 0040202). Так происходит потому, что числа располагаются по правилу: младший байт имеет меньший адрес.

Это правило позволяет узнать ещё об одной особенности команд процессора. Первая команда mov al, data_8, занимающая пять соседних байтов в памяти компьютера, выглядит в отладчике так:

mov al, data_8 АО 00204000

Очевидно, четыре идущих подряд байта 00 20 40 00 – это адрес числа data_8. Читая его справа налево, то есть в обратном порядке, получим 00402000 – адрес, видный в левом нижнем окне отладчика. Байт с таким адресом равен FD, то есть -3. В программе он помечен как data_8.

Т.о., любая команда процессора уже в самом первом своем байте содержит информацию о ее типе и длине (в нашем случае это байт А0). Только так можно всегда отличать конец одной команды от начала другой.