【发布时间】:2020-04-29 01:03:03
【问题描述】:
我正在尝试使用 malloc 在带有 nasm 的 asm Intel x86_64 中动态分配内存,但我不明白如何使用它。
例如,如果你想分配一个 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 的 SEGV on unknown address 0x000000000000 错误。
我这样调用函数:
int main(int ac, char **av)
{
char new_str = ft_strdup(av[1]);
return (0);
}
【问题讨论】:
-
是的,将所有代码显示为minimal reproducible example。还可以使用调试器查明错误并回溯到导致错误的原因。也就是说,
mov rdi, 20; call _malloc应该没问题。请注意,返回值在rax中,而不仅仅是eax,所以对于NULL,您必须进行测试(但这不是问题的原因)。也不清楚mov rax, r12应该做什么。此外,根据标准调用约定rdi是调用者保存的,因此您不能在_ft_strlen之后依赖它的值。在您致电_malloc时,r9也是如此,这可能是您的问题。 -
哦,对了,我忘了删除
mov rax, r12声明,我的错,让我编辑帖子添加其他功能 -
您为什么操作系统编程?请添加适当的标签。
-
@fuz 为什么会这样?在我看来是正确的。它也有效。正如我所说,问题是
malloc破坏了他用来保存字符串指针的r9。 -
是的,是的!你可以发布答案!我刚刚在 _malloc 调用之前添加了一个
push r9语句,在它之后添加了一个pop r9,它起作用了
标签: macos assembly x86-64 nasm