0

I am posting a message here because I am new to assembly programming. My goal today was to recode a strdup in assembler, so to save my first parameter which is a string (const char*), I have doubts when handling the RSP to reserve space for the string and how I reset it at the end.

However I'm not sure I did well, and I would like to have a review, and advice on what I could improve. Thanks in advance !

extern malloc
extern _ft_strlen
extern _ft_strcpy

section .text
    global  _ft_strdup

_ft_strdup:
        push        rbp                   ; prologue                      
        mov         rbp, rsp              ; prologue           
        sub         rsp, 8                ; reserve space for string                   
        mov         qword [rbp - 8], rdi  ; put first param on the stack
        call         _ft_strlen           ; strlen the first param
        mov         rdi, rax              ; put return value on the rdi register                       
        call        malloc                ; malloc rdi bytes                        
        cmp         rax, 0                ; check if malloc failed                                
        je          exit_prog                               
        mov         rdi, rax              ; put malloc address in rdi  (DEST)                            
        mov         rsi, qword [rbp - 8]  ; put source address in rsi (SRC)
        call        _ft_strcpy            ; copy                 
        add         rsp, 8                ; reset                     
        pop         rbp                   ; epilogue                             
        ret

exit_prog:
        xor             rax, rax
        add             rsp, 8                   
        pop             rbp                                     
        ret
fuz
  • 88,405
  • 25
  • 200
  • 352
  • 2
    Since you already have the length, `memcpy` can be faster than `strcpy` which has to search for the terminator again. Also, you misalign the stack by adjusting by an even multiple of 8 before your `call`s. See https://stackoverflow.com/questions/51070716/glibc-scanf-segmentation-faults-when-called-from-a-function-that-doesnt-align-r - some functions (like apparently `malloc` in the build of libc you're using) happen not to fault with a misaligned stack pointer, but it's best to follow the ABI. – Peter Cordes May 16 '23 at 01:38
  • 2
    Also, you don't need a stack frame and you can merge the epilogue. Use `test rax, rax` and `xor eax, eax` for smaller code. You know `rax` is zero in the error case so you don't even need to bother clearing it. Oh, and better not call your label `exit_prog` since it only returns from the function :) – Jester May 16 '23 at 01:39
  • 6
    Code-review questions about code you've tested and think is correct are a better fit for https://codereview.stackexchange.com/. Last I checked, they're off-topic for Stack Overflow. See [A guide to Code Review for Stack Overflow users](https://codereview.meta.stackexchange.com/q/5777) – Peter Cordes May 16 '23 at 01:40
  • 3
    You have a buffer overflow: You didn't allocate space for the null terminator. – Raymond Chen May 16 '23 at 04:07

0 Answers0