Гость Опубликовано 11 марта, 2005 Жалоба Поделиться Опубликовано 11 марта, 2005 Здравствуйте! Некоторое время я пользовался для выделения памяти malloc'ом и ему подобными функциями. Но возникла необходимость добиться такого же эффекта при помощи не библиотечных функций, а системных вызовов. Насколько я понял, в Линухе для этих целей используется вызов brk, устанавливающий конец сегмента данных в новое значение. Означает ли увеличение сегмента данных, что можно считать выделенной область памяти между старым и новым адресами конца сегмента данных? Как в таком случае получить адрес начала этой области (без использования sbrk), или в общем случае - каким образом в произвольный момент времени можно получить адрес конца сегмента данных? Т.е. должно ли выделение памяти выглядеть вместо p = malloc (0xffff); так p = <получить указатель на конец сегмента данных>; brk (p + 0xffff); ? И еще: man 2 brk brk and sbrk are not defined in the C Standard and are deliberately from the POSIX.1 standard Означает ли это, что существует еще один, соответствующий POSIX системный вызов для тех же целей? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
EL[michlen] Опубликовано 12 марта, 2005 Жалоба Поделиться Опубликовано 12 марта, 2005 Вот очень неплохой пример (с Linux.com): section .bss var1 resb 1 section .text ; ;allocate memory ; %define LIMIT 0x4000000 ; about 100Megs mov ebx,0 ; get bottom of data segment call sys_brk cmp eax,-1 ; ok? je erro1 add eax,LIMIT ; allocate +LIMIT memory mov ebx,eax call sys_brk cmp eax,-1 ; ok? je erro1 cmp eax,var1+1 ; has the data segment grown? je erro1 ; ;use allocated memory ; ; now eax contains bottom of ; data segment mov ebx,eax ; save bottom mov eax,var1 ; eax=beginning of data segment repeat: mov word [eax],1 ; fill up with 1's inc eax cmp ebx,eax ; current pos = bottom? jne repeat ; ;free memory ; mov ebx,var1 ; deallocate memory call sys_brk ; by forcing its beginning=var1 cmp eax,-1 ; ok? je erro2Что непонятно - спрашивайте. Цитата: brk and sbrk are not defined in the C Standard and are deliberately from the POSIX.1 standard Означает ли это, что существует еще один, соответствующий POSIX системный вызов для тех же целей? Нет, это означает, что он только в POSIX и существует, а в стандарте С его нет. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Ineu Опубликовано 13 марта, 2005 Жалоба Поделиться Опубликовано 13 марта, 2005 Да... Зря я так доверял печенью. Написал пост, потом гляжу - а я уж и аноним Спасибо за ответ. Только одно уточнение: перебивая фразу их мана, пропустил слово: are deliberately excluded from the POSIX.1 standard Вроде мелочь, а смысл не тот А то, что в Си-стандарте он не определен, а из ПОЗИКСа умышленно исключен, наводит на некоторые размышления Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Ineu Опубликовано 13 марта, 2005 Жалоба Поделиться Опубликовано 13 марта, 2005 Ага... вот и вопросы появились... Дайте, пожалуйста, ссылку на полный вариант приведенного кода (если она у Вас есть, конечно ). В частности, меня интересет функция sys_brk, исходя из того, что адрес ей передается в ebx, я могу предположить, что в ней и происходит обращение к системному вызову. Но и только - предположить Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
EL[michlen] Опубликовано 14 марта, 2005 Жалоба Поделиться Опубликовано 14 марта, 2005 Нет, полной версии кода у меня нет. Но в данном случае, функция sys_brk просто показывает, что происходит обращение к системному вызову - не зацикливайтесь на регистрах, думаю и так понятно. А чем не устраивает sbrk? Это, как написано в мане, не системный вызов, а оболочка к нему, но сильно это сути не меняет. Аналогичный вопрос и про malloc. Или речь об ассемблере без использования библиотеки С? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Ineu Опубликовано 14 марта, 2005 Жалоба Поделиться Опубликовано 14 марта, 2005 1. Цитата: в данном случае, функция sys_brk просто показывает, что происходит обращение к системному вызову Показывать-то показывает, но, например, следующий кусочек кода: mov ebx,0 ; get bottom of data segment call sys_brk Получить таким образом дно сегмента данных (согласно мана) можно именно используя sbrk: data = sbrk (0); А вот такое совсем не укладывается в синтаксис sbrk: add eax,LIMIT ; allocate +LIMIT memory mov ebx,eax call sys_brk которому должно передаваться смещение относительно текущего конца сегмента, а не полный адрес... Вот потому меня эта функция и заинтересовала... 2. Цитата: Или речь об ассемблере без использования библиотеки С? Именно. Хочется получить возможно более маленький бинарник, причем - статически слинкованный. Как совместить эти два требования с использованием libc, я не представляю. А ведь системные вызовы ничуть не хуже... Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
EL[michlen] Опубликовано 15 марта, 2005 Жалоба Поделиться Опубликовано 15 марта, 2005 Сам не сталкивался, интересно стало. Вот что нашёл про sbrk(): #include <string.h> #include <stdio.h> void *sbrk(int); main() { unsigned int count = 100; char *ptr; ptr = sbrk(count); if (ptr == (char *)-1) { perror("No available space for sbrk\n"); return; } strcpy(ptr, "String of data:"); strcat(ptr, "another string added\n"); fputs(ptr, stdout); } С этим всё просто. А вот как получить (а не установить) текущий адрес конца области данных с использованием только brk(), мне неизвестно. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Ineu Опубликовано 15 марта, 2005 Жалоба Поделиться Опубликовано 15 марта, 2005 Благодарю за ответ. Все равно ничего не получается Пойду почитаю исходники glibc, что за sbrk() такой... Хотя все равно это кажется какой-то бессмыслицей: назначить адрес можно, а получить нельзя. Как мне кажется, смысл в таком может быть только в одном случае - если _все_ исполняемые файлы запускаются с фиксированными адресами конца .data, но это полная ерунда, IMHO Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
EL[michlen] Опубликовано 15 марта, 2005 Жалоба Поделиться Опубликовано 15 марта, 2005 Цитата: если _все_ исполняемые файлы запускаются с фиксированными адресами конца .data, но это полная ерунда, IMHO Конечно ерунда, я могу статически навыделять разный размер памяти. Цитата: Хотя все равно это кажется какой-то бессмыслицей: назначить адрес можно, а получить нельзя. Действительно странно. Наверняка это можно сделать, но явно не средствами brk - он же статус возвращает, а не адрес. Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
EL[michlen] Опубликовано 15 марта, 2005 Жалоба Поделиться Опубликовано 15 марта, 2005 Хы, а вызов sys_brk вообще имеет вид asmlinkage unsigned long sys_brk(unsigned long brk)... Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Ineu Опубликовано 15 марта, 2005 Жалоба Поделиться Опубликовано 15 марта, 2005 Цитата: Конечно ерунда, я могу статически навыделять разный размер памяти. Ну... можно запускать бинарник с начальным адресом .data = фиксированный конечный адрес - размер всего статически выделенного Цитата: Наверняка это можно сделать, но явно не средствами brk - он же статус возвращает, а не адрес. Ага. В man brk есть ссылка на getrlimit, но это вообще предел потребляемых ресурсов: resource moust be one of: ... RLIMIT_DATA The maximum size of the process's data segment (initialized data, uninitialized data, and heap). This limit affects calls to brk() and sbrk(), which fail with the error ENOMEM upon encountering the soft limit of this resource Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.