2012-04-25 2 views
2

Итак, как вызов, так и для производительности, я пишу простой сервер в сборке. Единственный способ, которым я знаю, - это системные вызовы. (через int 0x80) Очевидно, мне понадобится больше памяти, чем выделено при сборке или при загрузке, поэтому я прочитал и решил, что хочу использовать sbrk(), главным образом потому, что я не понимаю mmap(): pLinux sbrk() как syscall в сборке

Во всяком случае, Linux не обеспечивает прерывания для sbrk(), только brk().

Итак ... как найти текущий разрыв программы для использования brk()? Я думал об использовании getrlimit(), но я не знаю, как получить ресурс (идентификатор процесса, который я предполагаю), чтобы перейти к getrlimit(). Или мне нужно найти другой способ реализации sbrk()?

+1

Добро пожаловать в переполнение стека! «Единственный способ, которым я знаю, - это системные вызовы». Также есть вызовы библиотеки, такие как 'sbrk'. Или вы имеете в виду «в сборке без libc»? –

+1

Я не знал, как делать вызовы в библиотеке. (и по-прежнему не знаете, как), по вашему мнению, вызовы библиотеки быстрее, чем системные вызовы? –

+0

'mmap' прост. Однако это не хорошо для небольших ассигнований. – doug65536

ответ

1

Функция sbrk может быть реализована путем получения текущего значения и вычитания требуемой суммы вручную. Некоторые системы позволяют получить текущее значение с brk(0), другие отслеживают его в переменной [, которая инициализируется адресом _end, который устанавливается компоновщиком, чтобы указать на начальное значение разрыва].

Это очень специфичная для платформы вещь, поэтому YMMV.

EDIT: В Linux:

Однако реальная система Linux вызов возвращает новый прорыв программы на успех. При сбое системный вызов возвращает текущий разрыв. Функция обертки glibc выполняет некоторую работу (т. Е. Проверяет, является ли новый разрыв меньше, чем addr), чтобы предоставить возвращаемые значения 0 и -1, описанные выше.

Итак, из сборки вы можете назвать это абсурдным значением, например 0 или -1, чтобы получить текущее значение.

Помните, что вы не можете «освободить» память, выделенную через brk - вам может понадобиться просто связать функцию malloc, написанную на C. Вызывать функции C из сборки не сложно.

+0

Или OP может сделать системный вызов 'mmap' с' MAP_ANONYMOUS | MAP_PRIVATE', чтобы получить память, и 'munmap', чтобы освободить его. Это более дорого, чем управление вашей памятью в пользовательском пространстве, но было бы намного легче сделать из сборки ... –

+2

«Имейте в виду, что вы не можете« освободить »память, выделенную через brk». Но «man brk» говорит: «Увеличение разрыва программы влияет на выделение памяти для процесса, а уменьшение разрыва освобождает память». Так как же вы не можете «освободить» память, выделенную через brk? – automaton

+0

@automaton Это небезопасно, потому что некоторая другая функция, которую вы вызывали после выделения этой памяти, могла выделить больше памяти «поверх». Вам нужно написать всю систему управления памятью. – Random832

0

Источник:

#include <unistd.h> 
#define SOME_NUMBER 8 
int main() { 
    void *ptr = sbrk(8); 
    return 0; 
} 

Compile использования с опцией Ассамблеи Output

gcc -S -o test.S test.c 

Тогда посмотрите на код ASM

_main: 
Leh_func_begin1: 
    pushq %rbp 
Ltmp0: 
    movq %rsp, %rbp 
Ltmp1: 
    subq $16, %rsp 
Ltmp2: 
    movl $8, %eax 
    movl %eax, %edi 
    callq _sbrk 
    movq %rax, -16(%rbp) 
    movl $0, -8(%rbp) 
    movl -8(%rbp), %eax 
    movl %eax, -4(%rbp) 
    movl -4(%rbp), %eax 
    addq $16, %rsp 
    popq %rbp 
    ret 
Leh_func_end1: 

Там нет системного вызова для него, но вы должны сможет по-прежнему звонить

+0

Я связал бинарный статический файл на fedora16/x86 и objdumped. Я видел, что __sbrk называет __brk, который вызывает brysc syscall (syscall 45) –

+0

Возможно, но то, что вы разместили, все еще зависит от внешней реализации _sbrk, связанной в –

+0

Да, как я уже упоминал, нет системного вызова для sbrk (по крайней мере на моей машине, и я уверен, что он исключен из стандарта Unix в качестве системного вызова), поэтому для вызова sbrk вам нужно будет связать его в 'libc', чтобы он был реализован. – lukecampbell

Смежные вопросы