string - 在 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
解决方案
最后,我从头开始重写了函数 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
推荐阅读
- python - 需要帮助从篮球参考中抓取 HTML
- html - 虚线边框在 chrome 中显示为“实线”
- microsoft-teams - #microsoft-teams 中群组聊天与个人聊天的区别
- flutter - 从 CodeMagic 上传二进制 App Store Connect
- json - 如何同时过滤两个 JSON 字段(SwiftUI)
- binary - 如何将十进制转换为 8 位有符号二进制?
- python - 尝试使用 MS Graph API 在 MS Teams 中创建频道时出现 500 内部错误
- r - 在ggplot中绘制断开的线
- iframe - 如何使用 Selenium 和 python 编程在亚马逊中处理没有 iframe 的“邮政编码”窗口弹出
- shell - 我无法从 shell 脚本中的文本中删除新行(使用 sed 和 grep)