Как использовать Mallo c в ASM - PullRequest
0 голосов
/ 11 января 2020

Я пытаюсь использовать mallo c для динамического выделения памяти в asm Intel x86_64 с помощью nasm, но я не понимаю, как его использовать.

Например, если вы хотите выделить 8-байтовая область памяти, я должен положить в стек sh 8, а затем вызвать mallo c, как это?

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

Я попробовал оба, но ни один из них не сработал, и я не нашел документации mallo c для nasm.

Я пытаюсь использовать mallo c, чтобы перекодировать функцию 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, я получаю ошибку SEGV on unknown address 0x000000000000 от sanitize .

Я вызываю функцию так:

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