在汇编语言中,_malloc 函数具体是做什么的?

21
public main
main proc near
push    ebp
mov     ebp, esp
and     esp, 0FFFFFFF0h
sub     esp, 30h
mov     dword ptr [esp], 8 ; size
call    _malloc
mov     [esp+2Ch], eax
mov     dword ptr [esp+4], 4
mov     eax, [esp+2Ch]
mov     [esp], eax
call    __start

上面的代码表示我正在开发的一个大项目的一部分。我试图将这段代码转换为C语言等价代码,但我很难理解malloc的工作原理。

我认为8个字节应该是所分配内存的大小;然而,我对于这行代码不太确定。

mov      eax, [esp+2ch] 

malloc函数对eax寄存器做了什么?

而且,这段代码是否等效于C代码?

int main(void)
{
int *ptr1;
ptr1 = (int *)malloc(sizeof(8));
*ptr1 = 4;
__start(*ptr1);
2个回答

26

函数 malloc() 将分配一个大小为 size 字节的内存块。如果可以分配所需内存,则返回指向该内存块开头的指针。

注意:接收到的内存块的内容未初始化。

malloc() 的语法:

void *malloc ( size_t size );

参数:

内存块的大小(以字节为单位)。

返回值:

如果请求成功,则返回指向内存块的指针。 如果函数无法分配所请求的内存块,则返回 NULL;使用大小为零调用 malloc() 也可能返回 NULL。

这篇由 Lawlor 博士撰写的 CS 301 讲座所述:

Calling Malloc from Assembly Language

It's a pretty straightforward function: pass the number of BYTES you want as the only parameter, in rdi. "call malloc." You'll get back a pointer to the allocated bytes returned in rax. To clean up the space afterwards, copy the pointer over to rdi, and "call free" (I'm leaving off the free below, because you need the stack to do that properly).

Here's a complete example of assembly memory access. I call malloc to get 40 bytes of space. malloc returns the starting address of this space in rax (the 64-bit version of eax). That is, the rax register is acting like a pointer. I can then read and write from the pointed-to memory using the usual assembly bracket syntax:

mov edi, 40; malloc's first (and only) parameter: number of bytes to allocate
extern malloc
call malloc
; on return, rax points to our newly-allocated memory
mov ecx,7; set up a constant
mov [rax],ecx; write it into memory
mov edx,[rax]; read it back from memory
mov eax,edx; copy into return value register
ret

Rather than copy via the ecx register, you can specify you want a 32-bit memory write and read using "DWORD" in front of the brackets, like this:

mov edi, 40; malloc's first (and only) parameter: number of bytes to allocate
extern malloc
call malloc
; on return, rax points to our newly-allocated memory
mov DWORD [rax],7; write constant into memory
mov eax,DWORD [rax]; read it back from memory
ret

关于汇编语言中的malloc,请查看此链接malloc


3
x84_64和x86在各种操作系统上具有不同的调用约定,因此这个答案只是间接相关的。例如,在OP的情况下,参数显然是通过堆栈传递的,而不是在寄存器中传递的。 - Kerrek SB
3
你为什么在谈论x86_64? - David Heffernan

4
我想强调一些在其他很好的答案中没有提到的内容。 malloc 内部是如何工作的?它在汇编中执行什么操作来创建所需的内存?
根据这个网站的说法,malloc 和其他内存调用使用操作系统 API 函数在堆上分配和释放内存。

3
正是我在寻找的答案,非常感谢! - Dan

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