» Главная
eXcode.ru » Статьи » Assembler
» Новости
» Опросы
» Файлы
» Журнал



Пользователей: 0
Гостей: 7





Оперативная память




Адресация памяти.

Каждая ячейка памяти имеет свой адрес - 32 битное смещение (в байтах) от начала сегмента. Сегмент определяется сегментным регистром (cs, ds, ss, es, fs, gs) и может указываться в командах при работе с памятью. Некоторые команды не поддерживают префикс замены сегмента.
Рассмотрим пример на основе команды mov.

Пример:

mov eax,fs:[0] - поместить в регистр eax число из сегмента, селектор которого находится в регистре fs, со смещением от начала сегмента - 0.

Т.к eax - 32 битный регистр, то из памяти считывается 32 бита.
Нельзя использовать более одного операнда "память" в команде.

-------------------------------

Смещение указывается в квадратных скобках, и может быть следующего формата: [Base+Index*{1,2,4,8}+число.] где Base - любой 32 битный регистр общего назначения, а Index - любой 32 битный регистр общего назначения кроме esp. Каждое из слагаемых может отсутствовать.

Пример:

mov ecx,dword ptr [eax+ecx*4-10] ;поместить в ecx двойное слово по адресу eax+ecx*4-10
mov cx,word ptr [edx+43]
mov byte ptr [ecx+edx],al ;записать в память по адресу ecx+edx значение регистра al

В документации смещение в памяти часто называют указателем (pointer) или адресом.
Разные команды работают с разными сегментами памяти по умолчанию.
Windows устроен так, что вы можете использовать все сегменты как один и тот же (кроме FS, используемый для SEH). Пока не указывайте префиксы замены сегмента, при адресации ячейки памяти обращайте внимание только на смещение.

-------------------------------

Обозначение памяти в программе.

Для обозначения строки (массива) байт, слов или двойных слов используются операторы db, dw и dd соответственно.Текстовые строки заключаются в двойные или одинарные кавычки.

Пример:

AnyLabel db 10 ;Определить 1 байт, равный 10

MsgString db ′Текстовая строка′,0 ;определить текстовую строку, с последним байтом равным нолю (ASCIIZ формат. Часто используется функциями Windows. Ноль обозначает конец строки. В документации упоминается как "null-terminated string")

SomeDwords dd 18,30h,′axyz′ ;определить массив двойных слов.

TenX db 10 dup (′X′),′YZ′ ;определить 10 байт, равных символу "X", при помощи оператора dup и два последних байта "YZ"

UnDefWord dw ? ;определить слово, изначальное значение которого нам неважно.

-------------------------------

Типы данных word и dword хранятся в памяти в перевернутом виде. При считывании двойного слова из строки байт MsgString получим значение "скеТ"
Для обозначения меток в программе используют следующую форму записи: AnyLabel:
Ими обычно обозначаются участки программы, на которые передается управление при помощи команд перехода. Метки и названия переменных не могут начинаться с цифры, состоят из любой комбинации английских букв и символов "_", "$", "@", "?". Последние три символа лучше не использовать.

Для получения адреса в памяти метки используется оператор offset.
Чтобы узнать размер массива данных используйте оператор size
Для переопределения типа данных используется оператор ptr.
Оператор $ используется для получения смещения текущего байта.

Пример:

mov ecx,offset SomeDwords+4 ;поместить в регистр ecx адрес в памяти строки SomeDwords +4.
mov cl,size TenX ;поместить в cl размер массива TenX (12).
mov edx,dword ptr [MsgString] ;поместить в edx двойное слово (4 байта - 4 символа) из строки MsgString.
Т.к edx - 32 битный регистр, а строка MsgString определена как строка байт, то нужно использовать оператор переопределения типа.

Символы - это 8 битные числа. Для определения числового значения символа можно использовать таблицу символов из Windows.

-------------------------------

Сегменты в программе.

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

-------------------------------

Стэк (Stack)

Стэк - это область оперативной памяти, начало которой находится по адресу ss:esp
Значение регистра esp называется адресом вершины стэка.
Для помещения числа в стэк используется команда push, для извлечения - pop.
При помещении 32 битного числа в стэк (push), происходит следующее:

1)уменьшение значения регистра esp на 4 ( размер dword′а).
2)запись числа по адресу ss:esp
Таким образом стэк "растет" вниз, от больших адресов памяти к меньшим.

Пример:

push eax ;поместить значение регистра eax в стэк
В стэк желательно помещать только 32 битные значения.
pop ecx ;извлечь из стэка число в регистр ecx
Команда pop ecx работает следующим образом:
mov ecx,dword ptr ss:[esp]
add esp,4

После выполнения этих команд (или команды pop ecx) значение ячейки памяти по адресу [esp-4] не изменится, но считается недействительным т.к. следующая команда push, другие команды работы со стэком, или возникшее прерывание перезапишут это значение, а также другие, с еще меньшим смещением.

-------------------------------

Строчкой .model flat,stdcall задается модель памяти (flat для программ под Windows), и алгоритм работы макроса вызова процедур (stdcall для функций Windows).

-------------------------------


.386 ;используем команды 386 процессора
;все последующие процессоры их также поддерживают.
.model flat,stdcall ;программа под Windows (см выше).
MAX_COMPUTERNAME_LENGTH equ 15
UNLEN equ 256
extrn GetComputerNameA:proc ;используемые внешние функции
extrn GetUserNameA:proc
extrn MessageBoxA:proc
extrn ExitProcess:proc
.data ;сегмент данных
MTitle db ′Computer / User name′,0 ;ASCIIZ строка - заголовок сообщения
CompNameSize dd MAX_COMPUTERNAME_LENGTH+1
UserNameSize dd UNLEN+1
MBuffer db MAX_COMPUTERNAME_LENGTH+UNLEN+1+3 dup (?) ;неопределенный массив.
;В нем будет формироваться строка с именем компьютера и пользователя
.code ;сегмент кода
start: ;метка начала программы
;функция GetComputerNameA возвращает имя компьютера по адресу из первого параметра,
;и количество символов в имени по адресу из второго параметра.
call GetComputerNameA,offset MBuffer,offset CompNameSize
mov eax,offset MBuffer ;eax= адресу массива MBuffer
;(в котором уже находится имя компьютера)
add eax,dword ptr [CompNameSize] ;добавим к eax количество символов в
;имени компьютера. Получим адрес конца текстовай строки.
mov dword ptr [eax],′X / ′ ;добавим к концу строки 4 символа (X для теста).
add eax,3 ;прибавим к смещению конца строки 3
;(по адресу eax будет символ X)
call GetUserNameA,eax,offset UserNameSize ;передадим в качестве адреса
;для возврата имени пользователя конец строки, по которому
;находится символ X, он будет перезаписан)
call MessageBoxA,0,offset MBuffer,offset MTitle,0 ;отобразим строку,
;состоящую из имени компьютера, разделителя и имени пользователя.
call ExitProcess,0 ;вызовем функцию завершения программы.
;если этого не сделать, выполнение пойдет дальше
;и Windows выведет сообщение об ошибке.
ends ;конец сегментов (можно и не писать)
end start ;конец программы, точка входа


------------------------------

Загрузите программу отладчиком. Если вы используете SoftIce (Symbol Loader из меню пуск), то для того чтобы показать / спрятать окошко с данными введите команду wd. Для отображения данных используйте команды db,dw и dd.
Как только вы увидите инструкции программы, найдите смещение массива MBuffer в памяти (из операндов инструкций), и отобразите его содержимое в окне с данными. По ходу выполнения программы (по нажатию клавиши F10), вы увидите, как содержимое массива будет меняться.
К началу статьи





Добавил: LedWormДата публикации: 2006-01-21 10:21:57
Рейтинг статьи:3.00 [Голосов 7]Кол-во просмотров: 10805

Комментарии читателей

Всего комментариев: 0
Ваше имя: *
Текст записи: *
Имя:

Пароль:



Регистрация

Каким ICQ-клиентом вы пользуетесь?
Стандартным ICQ - клиентом.
11% (23)
Miranda 'ой
13% (29)
крысой - &RQ
5% (10)
Своим собственным :)
4% (8)
Не пользуюсь, так как сижу на модеме :(
1% (3)
Не пользуюсь, мне и так хорошо ...
6% (13)
Qip'ом
56% (121)
Другим
4% (8)

Проголосовало: 215
Два программера в дупель пьяные из кабака выходят, один дpугому говоpит:
- Hу что, включай автопилот.
- А у меня его нету.
- Hу тогда включай эмулятоp автопилота.
Рейтинг: 5.5/10 (2)
Посмотреть все анекдоты