Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Работа с большой областью оперативки из Ассемблера


Страницы:   1 2

Yury Yakhno ©   (2002-08-07 23:46:00) 

Здравствуйте, уважаемые мастера.
Знает ли кто-нибудь решение этой проблемы:
Есть неразрывная область оперативной памяти размером до нескольких десятков мегабайт. На неё указывает Pointer. В ассемблерном коде нужно получить каждый байт по очереди. Проблема в том, что если написать:

var
M:Pointer;
N:Cardinal;
.
.
.
GetMem(M, N);
asm
.
.
.
mov ESI,M
.
.
.
inc ESI
mov AL,[ESI]
.
.
.
end;


то это работает на маленьких областях оперативной памяти, но если области большие, то надо ещё переходить через границу сегмента данных.
Кто-нибудь сталкивался с этой проблемой? Не подскажет ли кто-нибудь, например, как узнать какой сегментный регистр используется для моих данных (ds, es, gs, fs), или какая модель адресации используется?


Digitman   (2002-08-08 15:11:00) [21]

Добавлю только к выступлению уважаемого Слесаря, что обращение по смещению в любом текущем сегменте за пределы 64к совершенно необязательно требует работу в защищенном режиме. На современных машинах это вполне успешно реализуемо и в реальном режиме DOS, выполняемой CPU не ниже i80386. При этом, установив единожды нужные сегментные регистры и имея достаточно памяти (при окрытой 20-й адресной линии) можно запросто обращаться к любому участку физ.памяти, не заботясь более о содержимом сегментных регистров


Слесарь Матерящийся   (2002-08-08 14:46:00) [22]

>>>Насколько я знаю, Pointer - 32 битное смещение относительно сегмента данных программы.

В принципе так. Но видимо, вы путаете две модели памяти -- "традиционную" сегментированную для DOS и flat (protected mode).

В режиме адресации flat вы (в принципе) можете обращаться к любому адресу в рамках 0..4 Гб. Для этого вы можете использовать индексные регистры или ebx.

Модель flat подразумевает перекрытие сегментов адреса и данных в одном адресном пространстве.

Так, например (например!), если по адресу 0x04567870 в сегменте кода записан байт 0x45, то он будет виден в сегменте данных по тому же (0x04567870) адресу.
Разумеется, сейчас мы не учитывали принципы работы виртуальной памяти и т.п. Речь шла только об адресации.

--------

>>>Так вот если выделить себе мегов сто и зациклить ESI на inc, не достигнет ли он своего максимального значения, а потом обнулится

В реальном режиме DOS-программ такое могло быть. Но в protected mode работает механизм защиты памяти.
Вы можете обращаться т_о_л_ь_к_о к заранее выделенной области памяти.
Если вы обратились "мимо", сработает механизм защиты и вы получите msg "Access violation".
Просто контролируйте, чтобы указатель не переходил границы выделенной области.
Так, к примеру, если выделенный фрагмент расположен по адресу
0x00770000 и имеет длину 0x00004000 байт, то диапазон памяти, к которому можно обращаться -- 0x00770000..0x00773FFF

//


Digitman   (2002-08-08 14:04:00) [23]

DS = ES = CS = SS

размер "сегмента", о коем ты так беспокоишься, формально может достигать 4GB - это предостаточно для того , чтобы надолго забыть обо всем касаемом "сегментов"


Yury Yakhno   (2002-08-08 13:53:00) [24]

> Anatoly Podgoretsky © (07.08.02 23:49)
> Какая версия Дельфи?

Delphi 6

> Слесарь Матерящийся (08.08.02 00:25)
> Модель flat. [Местами stdcall. Ой. Шютка :)]
> 32 бита. плоский мир. про сегментные регистры просто необходимо забыть.
> и что означает:
> "работает на маленьких областях оперативной памяти, но если области
> большие, то надо ещё переходить через границу сегмента данных."
> -- совершенно непонятно. Поясните, pls.

Насколько я знаю, Pointer - 32 битное смещение относительно сегмента данных программы. Когда я заношу указатель в ESI, он уже имеет какое-то значение. Так вот если выделить себе мегов сто и зациклить ESI на inc, не достигнет ли он своего максимального значения, а потом обнулится?
Скорее всего, я просто чего-то не догоняю, но регулярно получаю Access Violtation при обращении к [ESI] через некоторое время после начала работы.

> Юрий Зотов © (08.08.02 08:56)
> Не только сегментые регистры - даже ассемблер не нужен.
> Простое приведение Pointer к DWORD решает проблему
> адресной арифметики.

Разумеется, но я с каждым байтом ещё определённые действия произвожу. Ассемблер мне для этого нужен. А про DWORD я выше писал.


Юрий Зотов   (2002-08-08 08:56:00) [25]

Не только сегментые регистры - даже ассемблер не нужен. Простое приведение Pointer к DWORD решает проблему адресной арифметики.


Слесарь Матерящийся   (2002-08-08 00:25:00) [26]

Модель flat. [Местами stdcall. Ой. Шютка :)]
32 бита. плоский мир. про сегментные регистры просто необходимо забыть.
и что означает:
"работает на маленьких областях оперативной памяти, но если области большие, то надо ещё переходить через границу сегмента данных."
-- совершенно непонятно. Поясните, pls.


Anatoly Podgoretsky   (2002-08-07 23:49:00) [27]

Какая версия Дельфи?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо