首页 > 解决方案 > How to use malloc in asm

问题描述

I'm trying to use malloc to allocate memory dynamically in asm Intel x86_64 with nasm, but I don't understand how to use it.

For exemple, if y want to allocate a 8 bytes memory area, should I push 8 on the stack and then call malloc, like this ?

extern _malloc

section .text
    global _my_function

_my_function:
    push 20
    call _malloc
    ret

Or should I move 20 to the rdi register, which is the normally the function's first argument like that ?

extern _malloc

section .text
    global _my_function

_my_function:
    mov rdi, 20
    call _malloc
    ret

I tried both but none of them worked and I didn't find any malloc documentation for nasm.

I'm trying to use malloc in order to recode the strdup function from the string library, here's my actual code :

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)

When I call ft_strdup, I get a SEGV on unknown address 0x000000000000 error from sanitize.

I call the function this way :

int main(int ac, char **av)
{
    char new_str = ft_strdup(av[1]);
    return (0);
}

标签: macosassemblyx86-64nasm

解决方案


解决方案 -小丑

带有 nasm 的 Intel x86_64 的 Malloc 使用情况

  • malloc 的字节进入rdi寄存器。
  • 返回指向rax寄存器中内存区域的指针。
mov rdi, 20
call _malloc

根据标准调用约定,您不能依赖 after call 的值,after rdicalls_ft_strlen也是如此。这是因为两个寄存器都是调用者保存的r9_malloc

为了保值r9

push r9
call _malloc
pop r9

装配编程技巧

  • 将您的所有代码显示为最小的可重现示例
  • 使用调试器来查明您的错误并回溯到导致错误的原因(您可以将gdb与一个很酷的.gdbinit文件一起使用)

推荐阅读