56 / 2 / 0
Регистрация: 19.10.2015
Сообщений: 98
|
||||||
1 | ||||||
Работа с памятью: адресация выделенной области памяти06.02.2017, 17:11. Показов 5656. Ответов 14
Привет, ребят! Допустим я создал (выделил) какой-то участок памяти (функция 48h).. Вооот И мне очень хотелось бы его как-то адресовать (в моем понимании адресовать - значит обращаться к нужному мне участку выделенной памяти и, при необходимости его изменять). По сути это просто буфер, в который я бы хотел запихивать данные, но я никак не пойму, как к нему обратиться.. Пробовал
0
|
06.02.2017, 17:11 | |
Ответы с готовыми решениями:
14
Работа с памятью, выделенной malloc Почему в данном случае работа с заранее выделенной памятью медленнее чем с динамической? Разница между выделенной памятью и общей памятью графического процессора? Почему у массивов типа char может быть утечка памяти, а у указателей char с выделенной памятью - нет? |
3408 / 1827 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
|
|
06.02.2017, 18:51 | 2 |
1
|
56 / 2 / 0
Регистрация: 19.10.2015
Сообщений: 98
|
|
06.02.2017, 19:01 [ТС] | 3 |
По идее функция возвращает адрес созданного блока памяти
0
|
3408 / 1827 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
|
|
06.02.2017, 19:24 | 4 |
Вот оно.
Функция возвращает сегментный адрес, грузите его в сегментный регистр, ну а дальше как обычно в модели small.
2
|
56 / 2 / 0
Регистрация: 19.10.2015
Сообщений: 98
|
|
06.02.2017, 19:49 [ТС] | 5 |
Хех! А у меня то tiny)) Но я нашел один вариант! Хотя это очень странно, но я смог оперировать с этим адресом с помощью stos.. А странность в том, что у меня после команды stos значение ax загружается не только по адресу
ES:DI , но и по адресу ds:DI . Почему так я ума не приложу! Ведь копируется только в ES! Почему вдруг скопировалось еще и в DS? Хотя мне это очень помогло.. Но тут явно что-то не так..Добавлено через 3 минуты Стой, стой! Сегментный! Значит это не смещение, а целый сегмент?! Что-то я тогда не понимаю.. Зачем тогда указывать размер в BX, если все равно выделяется целый сегмент? Или выделяется кол-во параграфов из BX, считая от начала сегмента? Вот сейчас, честно говоря, запутался совсем)))
0
|
Asm/C++/Delphi/Py/PHP/VBA
|
||||||||||||||||
07.02.2017, 00:31 | 6 | |||||||||||||||
Такого быть не может вообще никак. Ну разве что DS=ES
Код в студию, чтобы не гадать на кофейной гущи. Название модели - tiny, small и т.д. - это всё условно.
Типа такого:
1
|
19 / 187 / 0
Регистрация: 17.06.2013
Сообщений: 2,163
|
|
07.02.2017, 08:36 | 7 |
Понимаете вообще, если иметь дело с ассемблером, к примеру в Pascal Delphi.
То надо сначало, перед работая с регистрами, начало скопировать то что в них было, и после использования вернуть это на место. Мне почему то всегда так приходится... А как, почему, я не спрашивался. У вас по моему называется... Что то вроде попытки написать стек.
1
|
Модератор
|
|
07.02.2017, 08:46 | 8 |
Ixmil, то, о чём вы говорите - соглашение об использовании регистров в конкретном компиляторе.
1
|
19 / 187 / 0
Регистрация: 17.06.2013
Сообщений: 2,163
|
|
07.02.2017, 10:14 | 9 |
Ну это как то так:
Mov EAX, [EBX]; Я сам писал, алгоритм длинной строковой переменой. И оказалось спотыкался, на таких простых вопросах, на которых не ожидал. А потому пришол к выводу. Что ассемблер существует, для написания таких небольших подфункций, но сами функции, из них состоят. И как то думается что должно быть так. Добавлено через 19 минут Ну я бы сказал, что я сказал о самой такой общей необходимости. Которая при том то затронет, что то то нет. Добавлено через 1 час 7 минут Но в принципе, я отвечу, не слишком осознавая вопрос, но предопределяя его сопутствующие. Всякие недокументированные команды, я бы вообще сбросил со счетов, и писал бы длиннее но без них. А если вам городят о наикротчайшем коде, от того с повышенным КПД. То знаете есть такие иллюзии. Когда одно кажется не тем, что на деле. И КПД определить - как то очень сложно, а не просто.
0
|
3408 / 1827 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
|
|
07.02.2017, 11:07 | 10 |
Формат СОМ, да забирает всю память, а вот для ЕХЕ формата, память выделяется в зависимости от двух значений в заголовке программы MinAlloc MaxAlloc:
1
|
3408 / 1827 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
|
|
07.02.2017, 11:34 | 11 |
Функция возвращает сегментный адрес выделеного блока памяти, Загрузив его в сегмент, блок памяти можно использовать также как и сегмент данных т.е. DS : [offset X] или ES : [offset X]
Добавлено через 10 минут Ixmil, 1)Давайте не будем путать чистый ассемблер и встроенный. Несмотря на их схожесть. При работе со встроенным асмом, основную работу за Вас выполняет компилятор ЯВУ, в читстом всё должен продумать кодер. 2)Это не что то вроде... Память может понадобится в большенстве случаях, поэтому не видя кода говорить о каких-то стеках нельзя.
1
|
Asm/C++/Delphi/Py/PHP/VBA
|
|||||||||||||||||||||||||||||||
07.02.2017, 14:45 | 12 | ||||||||||||||||||||||||||||||
Их не копировать надо, а сохранять (в стеке обычно... хотя это и есть копирование, но так никто не выражается) и восстанавливать. В 32-битных программах это ebx, esi, edi. Ну и ebp, esp, разумеется (обычно это делается в прологах/эпилогах). И то, если они изменяются только.
p.s. В 64-битных кроме rbx, rsi, rdi, rbp, rsp сохраняются ещё r12..r15, xmm6..xmm15, если кому интересно... Что значит "выделяется целый сегмент"? Сегмент - это НЕ некая область памяти фиксированного размера, он может иметь размер 16 байт, а может быть сотни килобайт. И в регистре BX ты как раз указываешь размер этого сегмента. Потом тебе возвращается в регистре AX сегментный адрес, который ты записываешь в ES. Память в DOS организована в виде пары Сегмент:Смещение, линейный адрес получается как Сегмент*16 + Смещение, т.е. Адреса 1234h:0 = 1000h:2340h = 1200h:340h = 1230h:40h, так же как 0F000h:0FFF0h = 0FFFFh:0. Именно поэтому раз тебе выделяется вся память (оставшаяся доступная), твоя задача - лишь проверить, достаточно ли памяти тебе выделено. А дальше, если, например, твои переменные хранятся по смещению 200h, то ты можешь спокойно адресовать их через ds:200h, а можешь записать в ES значение DS (или CS в COM-программе) + 20h и адресовать через es:0. Второй случай есть смысл использовать, если тебе нужно много памяти, например, 64Кб. Или больше, тогда придётся менять ES несколько раз (или использовать DS, FS, GS, например). А если у тебя прога занимает 1Кб кода (+256 байт на PSP), то до конца сегмента кода (CS=DS=ES при старте программы) остаётся ещё 64256 байт (62,75 Кб), и вполне можно юзать привычные "переменные", а-ля:
heap , а вот в tasm/masm с этим сложно. В tasm вообще ничего нет, а в masm (link.exe) даже параметр /heap никакого эффекта не оказывает...Добавлено через 22 минуты Кстати, забыл сказать про стек. В com-программе стек находится в конце сегмента кода (SS=CS). Если памяти выделено >= 64Кб, то sp=0FFFEh. Если меньше, то sp<0FFFEh. Таким образом, для надёжности при использовании большого кол-ва памяти внутри сегмента кода (т.е. если максимум нужно заюзать 64Кб – размер кода – 256 на PSP – размер стека) нужно делать проверку:
В общем вот так:
1
|
56 / 2 / 0
Регистрация: 19.10.2015
Сообщений: 98
|
|
07.02.2017, 20:05 [ТС] | 13 |
Так, кажется большинство вопросов отпали!) Но появился очень интересный: что вообще делает функция 48h? Выделяет памяти за пределами программы, тем самым увеличивая доступную память? Непонятно также зачем использовать 4Ah, если она просто расширяет блок? Можно ведь контролировать размер блока при его создании, а максимальный размер блока, как я понимаю, превысить нельзя. (4Ah нужна скорей для сокращения блока, отведенного для программы) А насчет кода - нет смысла его прикреплять. Обычная комка (на данном этапе). Блок нужен для функции 0Ah (ввод строки). Мог бы сделать простой массив, но зачем-то решил заморочиться))).. Воот.. А теперь у меня уже спортивный интерес. Как видно эти функции - явный пробел в знаниях!
0
|
Asm/C++/Delphi/Py/PHP/VBA
|
|
07.02.2017, 21:14 | 14 |
Сообщение было отмечено NEWd как решение
Решение
Если проге выделена вся доступная память, то 48h больше ничего не выделит. Если ты видишь, что ah=48h/int 21h вернула в BX значение > 0, значит есть свободный блок (небольшой, скорее всего) по адресу ниже программы. 4Ah может как сокращать, так и расширять.
Для функции 0Ah ничего не нужно, никаких блоков памяти выделять. Если ты делаешь прогу формата COM, у тебя памяти будет предостаточно. И уж 80 байт тебе точно хватит на ввод строки. Если EXE, то там требуемый объём будет заложен в заголовок, тем более можно не беспокоиться...
1
|
56 / 2 / 0
Регистрация: 19.10.2015
Сообщений: 98
|
|
07.02.2017, 21:21 [ТС] | 15 |
Спасибо за помощь!)
0
|
07.02.2017, 21:21 | |
07.02.2017, 21:21 | |
Помогаю со студенческими работами здесь
15
Могут ли два приложения пользоваться одной и той же выделенной памятью? Адресация памяти Распределение и адресация памяти Сегментная адресация памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |