Как динамически выделить память для массива в сборке 8086 с помощью NASM - PullRequest
2 голосов
/ 06 апреля 2011

Так что мне нужно сделать что-то подобное в сборке

int *arr = malloc(sizeof (int) * size);

где пользователь вводит размер и в зависимости от размера вызывается цикл while для заполнения массива.

Так что мне нужен указатель на пространство, созданное malloc, как мне сделать это в заднице 86? Кроме того, где я могу сохранить этот указатель, чтобы я мог использовать массив позже. Сказать, что бинарный поиск на входе?

С уважением обр

Ответы [ 5 ]

2 голосов
/ 06 апреля 2011

Предположим, что вы находитесь под Win и создаете консольное приложение (в следующий раз опишите подробнее), решение, которое можно найти в языке Art Of Assembly (заглавными буквами, потому что это книга great ): 1003 *

13.3.6.1 Выделение памяти

Function (ah):     48h  
Entry parameters:  bx- Requested block size (in paragraphs)  
Exit parameters:   If no error (carry clear):  
                       ax:0 points at allocated memory block  
                   If an error (carry set):  
                       bx- maximum possible allocation size  
                       ax- error code (7 or 8)  

This call is used to allocate a block of memory. On entry into DOS,
bx contains the size of the requested block in paragraphs (groups of
16 bytes). On exit, assuming no error, the ax register contains the
segment address of the start of the allocated block. If an error
occurs, the block is not allocated and the ax register is returned
containing the error code.  
If the allocation request failed due to insufficient memory, the bx 
register is returned containing the maximum number of paragraphs actually
available.

13.3.6.2 Выделение памяти

Function (ah):    49h  
Entry parameters: es:0- Segment address of block to be deallocated  
Exit parameters:  If the carry is set, ax contains the error code (7,9)  

This call is used to deallocate memory allocated via function 48h above. The
es register cannot contain an arbitrary memory address. It must contain a
value returned by the allocate memory function. You cannot use this call to
deallocate a portion of an allocated block. The modify allocation function
is used for that operation.

13.3.6.3 Изменение выделения памяти

Function (ah):     4Ah
Entry parameters:  es:0- address of block to modify allocation size
                   bx- size of new block
Exit parameters:   If the carry is set, then ax contains the error code 7, 8,
                   or 9
                   bx contains the maximum size possible (if error 8)

This call is used to change the size of an allocated block. On entry, es must
contain the segment address of the allocated block returned by the memory
allocation function. Bx must contain the new size of this block in paragraphs.
While you can almost always reduce the size of a block, you cannot normally
increase the size of a block if other blocks have been allocated after the
block being modified. Keep this in mind when using this function.

стр. 719, если вам это нужно;)

2 голосов
/ 06 апреля 2011

Почему-то я догадываюсь, что это не то, что вы хотите сделать.

Проще говоря, неправильная сборка памяти при сборке не особенно проста.

Легко, если вы собираетесь выполнять вызов системной функции, в случае, если вам нужно понять соглашения о вызовах для подпрограмм и библиотек и компоновщиков операционной системы. Вы можете вызывать какую-то функцию ОС, возможно, через прерывание, и это, опять же, зависит от операционной системы.

Потому что, как правило, программы на ассемблере обычно имеют довольно статичные представления памяти и определяют свою собственную карту памяти. Вы можете выделить большой блок данных, а затем сопоставить свой собственный «malloc» с этим блоком. Оригинальный блок станет вашим, когда рутина загружается. Это, вероятно, ближе к тому, что вы хотите сделать, но, очевидно, это может быть гораздо больше работы.

Если вы не выделяете более одного массива за раз, просто определите блок в источнике сборки, который является «достаточно большим» (скажем, 10 000 целых чисел). Тогда вы можете просто использовать это.

Если вы вызываете некоторую подпрограмму выделения памяти, результат будет возвращен либо в стеке, либо в регистре. Затем вы либо оставите это значение в регистре, предназначенном для задачи удержания его до конца вашей обработки, либо просто сохраните значение в памяти где-то еще, а затем загрузите его, когда оно понадобится вам позже.

1 голос
/ 06 апреля 2011

Вы можете позвонить malloc() прямо из своего кода asm.Действительно!

В этом уроке показано, как это сделать.Не волнуйтесь, эта техника не ограничивается Mac OS X.

0 голосов
/ 27 марта 2016

Если вам не нужно, чтобы распределение продолжалось за пределами текущей функции, просто выделите в стеке:

; calculate allocation size in eax, for example
sub   esp, eax
; esp points to the memory

Если это функция, а не верхнего уровня, то функция должна использовать кадр стека (push ebp / mov ebp, esp, тело функции, leave / ret) для восстановления esp, поэтому Вы можете pop ваши другие регистры.

0 голосов
/ 27 марта 2016

C компилируется в Assembly, и сгенерированный код на Ассемблере также будет вызывать malloc.sizeof (int) должен быть 4 байта / 32 бита / слово в x86.

...