我正在尝试在nasm的Intel x86_64汇编中使用malloc动态分配内存,但是我不知道如何使用它。
例如,如果您想分配8个字节的内存区域,应该将8推送到堆栈上,然后调用malloc,像这样吗?
extern _malloc
section .text
global _my_function
_my_function:
push 20
call _malloc
ret
我应该将20移动到rdi寄存器,这通常是函数的第一个参数,就像这样吗?
extern _malloc
section .text
global _my_function
_my_function:
mov rdi, 20
call _malloc
ret
我尝试了这两个方法,但都没有起作用,而且我也没有在nasm中找到任何malloc文档。
我正在尝试使用malloc重新编写字符串库中的strdup函数,以下是我的实际代码:
extern _ft_strlen
extern _ft_strcpy
extern _malloc
section .text
global _ft_strdup
_ft_strdup:
push rsi
push rdi ; rdi = str
call _ft_strlen ; rax = ft_strlen(str)
mov r9, rdi ; save rdi (str) into r9
mov rdi, rax ; rdi = len
inc rdi ; rdi = len + 1
call _malloc ; rax = new_str (allocated)
cmp eax, 0 ; if malloc failed
je _failure ; └──► return NULL
mov rsi, r9 ; rsi = str
mov rdi, rax ; rdi = new_str
call _ft_strcpy ; ft_strcpy(new_str, str)
pop rdi
pop rsi
ret
_failure:
xor rax, rax
pop rdi
pop rsi
ret
section .text
global _ft_strcpy
_ft_strcpy:
push rdi
push rsi
jmp _loop
_loop:
mov r8b, BYTE [rdi] ; Save *dst into r8b
mov r9b, BYTE [rsi] ; Save *src into r8b
cmp r9b, 0 ; if *src == '\0'
je finish ; └──► exit from _loop
mov [rdi], r9 ; *dst = r9 (r9 = *src)
inc rdi ; dst++
inc rsi ; src++
jmp _loop
finish:
mov [rdi], r9 ; *dst = r9 (r9 = *src = '\0')
pop rsi
pop rdi
mov rax, rdi ; rax = initial value of dst
ret ; Return rax (dst pointer)
section .text
global _ft_strlen
_ft_strlen:
push rdi
xor rax, rax ; rax = 0
jmp _loop
_loop:
cmp [rdi], byte 0 ; if *str == '\0'
je finish ; └──► exit from _loop
inc rax ; rax++ (len)
inc rdi ; str++
jmp _loop
finish:
pop rdi
ret ; Return rax (len)
当我调用ft_strdup时,sanitize会报告一个“在未知地址0x000000000000上的SEGV”错误。
我是这样调用函数的:
int main(int ac, char **av)
{
char new_str = ft_strdup(av[1]);
return (0);
}
mov rdi, 20; call _malloc
应该是可以的。请注意返回值在rax
而不仅仅是eax
中,所以进行NULL
检查时需要测试它(但这不是问题的原因)。此外,不清楚mov rax, r12
的目的是什么。根据标准的调用惯例,rdi
是调用方保存寄存器,所以在_ft_strlen
后不能依赖于它的值。对于_malloc
调用中的r9
也是同样的情况,这可能是你的问题所在。 - Jestermov rax, r12
这条语句了。我的错,让我编辑帖子添加其他函数。 - lfalkaumalloc
销毁了他用来保存字符串指针的r9
。 - Jesterpush r9
语句,在其后添加了一个pop r9
,它起作用了。 - lfalkau