如何在8086汇编语言中使用NASM动态分配数组内存

6
我需要在汇编语言中执行类似于这样的操作。
int *arr = malloc(sizeof (int) * size);

用户输入尺寸后,基于该尺寸调用while循环以填充数组。

因此,我需要一个指向malloc创建的空间的指针,在ass 86中如何实现呢? 另外,我应该将这个指针存储在哪里,以便稍后使用数组,例如对输入进行二进制搜索?

问候, arr


由于缺少操作系统、32/64位等信息以及有关变量范围的任何上下文,因此对于32位Linux代码,您可以使用sys_brk系统调用来创建一些空间。我在StackOverflow上有一个[之前的答案],涵盖了这个问题:https://dev59.com/aJHea4cB1Zd3GeqPomZm#33903235。通常,在32位Linux中,`sys_brk`用于分配底层内存,_heap_(由malloc使用)最终将其划分为满足请求的部分。 - Michael Petch
5个回答

2
假设您正在Windows下创建一个控制台应用程序(下次请提供更多细节),在汇编语言艺术书中(因为这是一本很好的书,所以用大写字母表示)找到的解决方案是: 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 Deallocate Memory

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页;)


这些函数是DOS中断21h函数。您不能在MSWindows程序中使用它们。 "控制台应用程序"与DOS应用程序不同; MSWindows控制台应用程序无法使用DOS函数。 - ecm

2

我猜想您不是想要做这件事情。

在汇编语言中,简单地使用malloc分配内存并不容易。

如果您要调用系统函数,那么这很容易。但这需要您了解操作系统例程和库以及链接器的调用约定。您可能会通过一些种类的OS函数来调用它,也许是通过中断实现的,这又取决于操作系统。

因为通常情况下,汇编程序往往有非常静态的内存视图,并定义自己的内存映射。您可以分配一个大块数据,然后针对该块数据编写自己的“malloc”。当程序加载时,原始块将变成您的。这可能更接近于您想要做的事情,但显然需要更多的工作。

如果您不需要同时分配多个数组,只需在汇编源代码中定义一个“足够大”的块(例如10,000个整数)。然后您就可以直接使用它。

假设您确实调用了一些内存分配例程,则结果将返回堆栈或寄存器中。然后您可以将该值留在专门用于保存它的寄存器中,以供后续处理使用,或者您可以简单地将该值存储到其他地方的存储器中,然后在以后需要时加载它。


1

你可以直接从汇编代码中调用malloc()。真的!

这个教程展示了如何做到。别担心,这种技术不仅适用于Mac OS X。


1

如果您不需要分配超出当前函数作用域的空间,只需在堆栈上进行分配:

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

如果这是在函数内部而不是顶层,则该函数应使用堆栈帧(push ebp / mov ebp, esp,函数主体,leave / ret)来恢复esp,以便您可以pop其他寄存器。
通常情况下,您应将EAX舍入到16的倍数,以保留堆栈对齐。例如:add eax, 15 / and eax, -16。如果您的系统或函数没有维护更多的堆栈对齐,则仅为4。

0

C语言编译成汇编语言,生成的汇编代码也会调用malloc函数。 在x86架构中,int类型的大小应该是4字节/32位/dword。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接