首页 > 解决方案 > 在 asm x86-64 intel 语法中连接两个字符串

问题描述

我试图连接两个字符串,但我不断收到分段错误,有人可以帮助我解决我的代码可能有什么问题吗?谢谢!为了测试它,我只是用动态分配的内存创建字符串,这是一个课堂练习,所以我必须从我的函数获得的 2 个参数中释放内存

我的代码:

    ;int32_t strCmp(char* a, char* b)
    strConcat:
        push rbp    ;stack frame 
        mov rbp, rsp
        push r12 ; stringA
        push r13 ; stringB
        push r14 ; puntero inicio ; stringA
        push r15 ; puntero inicio ; stringB   
        mov r12, rdi
        mov r13, rsi
        mov r14, r12
        mov r15, r13
        xor rcx, rcx ;clean rcx to do len(stringA)+leng(stringB)+1
        call strLen  ; len stringA
        add rcx, rax
        mov rdi, r13 
        call strLen  ;  len stringB
        add rcx, rax
        mov rdi, rcx
        inc rdi
        call malloc
        ; now rax has a pointer to new concatenated string space

        .cicloA:        ;loop to iterate over 1st string
            cmp byte [r12], 0
            jz .cicloB
            xor rdx, rdx
            mov dl, byte [r12]
            mov byte [rax], dl
            inc r12
            inc rax
            jmp .cicloA

        .cicloB:        ;loop to iterate over 2th string
            cmp byte [r13], 0
            jz .fin
            xor rdx, rdx
            mov dl, byte [r13]
            mov byte [rax], dl
            inc r13
            inc rax
            jmp .cicloB

        .fin:
            ;add /0
            mov byte [rax], 0
            ;release memory
            mov rdi, r14
            call free
            mov rdi, r15
            call free 
            pop r15
            pop r14
            pop r13
            pop r12
            pop rbp
            ret

我的 strLen 函数是

    ;uint32_t strLen(char* a)
    strLen:
        push rbp    ;armo el stack frame 
        mov rbp, rsp
        xor rax,rax
        .avanzar:       ;loop para ver si llegue al fin de un string 
            cmp byte [rdi], 0   
            je .fin
            inc rdi
            inc rax
            jmp .avanzar
        .fin:
            pop rbp 
            ret

Valgrind 错误:

==18885== Invalid read of size 1
==18885==   at 0x400E4A: ??? (lib.asm:79)
==18885==   by 0x400C49: test_strConcat (main.c:79)
==18885==   by 0x400D28: main (main.c:109)
==18885== Address 0x2 is not stack'd, malloc'd or (recently) free'd

标签: stringassemblyx86-64nasmstrcat

解决方案


最后,我从头开始重写了函数 strConcat,现在它可以工作了。

strConcat:
    push rbp    ;armo el stack frame 
    mov rbp, rsp
    push rbx
    push r12 ; stringA
    push r13 ; stringB
    sub rsp, 0X08

    mov r12, rdi
    mov r13, rsi

    call strLen     ;loongitud del primer string
    mov ebx, eax
    mov rdi, r13
    call strLen     ;longitud del segundo string;
    add ebx, eax
    mov edi, ebx
    add edi, 1
    call malloc
    ; ahora rax tiene el puntero a nuevo string para concatenar
    ;limpio contadores
    xor r8, r8
    xor r9, r9
    .cicloA:        ;loop para colocar stringA en nuevo string
        cmp byte [r12 + r8], 0
        jz .cicloB
        mov dl, byte [r12 + r8]
        mov byte [rax + r8], dl
        inc r8
        jmp .cicloA

    .cicloB:        ;loop para colocar stringB en nuevo string
        cmp byte [r13 + r9], 0
        jz .borrar
        mov dl, byte [r13 + r9]
        mov byte [rax + r8], dl
        inc r8
        inc r9
        jmp .cicloB

    .borrar:
        ;agrego el cero al final
        mov byte [rax + r8], 0
        mov rbx, rax
        ;reviso si son el mismo puntero
        cmp r12, r13
        je .igualitos

        ;libero memoria
        mov rdi, r12
        call free
        mov rdi, r13
        call free
        jmp .final
    .igualitos:
        mov rdi, r12
        call free
    .final:
        add rsp, 0x08
        mov rax, rbx
        pop r13
        pop r12
        pop rbx
        pop rbp
        ret

推荐阅读