You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x64汇编字符串反转函数触发SIGSEGV错误求助

问题分析与解决

核心错误原因

  • 未初始化的目标缓冲区(rsi寄存器):你的汇编函数错误地将rsi用作反转后字符串的存储位置,但对应的C函数声明char* asm_func4(char *);仅定义了一个参数。在x86-64 System V调用约定中,rsi对应第二个函数参数,而调用方main只传入了一个参数,导致rsi的值未定义(从gdb调试信息看,它指向了只读内存区域),写入该地址直接触发SIGSEGV内存错误。
  • 字符串字面量的只读属性:即使修正参数问题,直接传入字符串字面量(如"Hello from asm_func4\n")也不可行——这类字面量存储在程序的只读数据段,尝试写入会触发内存保护机制。

修复步骤

1. 修改函数接口,添加目标缓冲区参数

更新头文件prog.h,让函数接收原字符串和可写目标缓冲区两个参数:

#pragma once
char* asm_func4(char *src, char *dest);

2. 调整汇编代码适配新接口

修正寄存器使用逻辑,同时优化字符串长度计算(避免原字符串无换行符时的索引错误):

asm_func4:
        push rbp                ; 保存rbp寄存器
        mov rbp, rsp            ; 建立规范栈帧(可选但更严谨)
        call _strlen            ; 计算源字符串长度(rdi为src参数)
        mov rdx, rax            ; 将长度复制到rdx作为反向计数器
        ; 检查末尾是否为换行符,再决定是否调整长度
        cmp byte [rdi+rdx-1], 0x0A
        je .adjust_newline
        jmp .skip_adjust
.adjust_newline:
        sub rdx, 1              ; 去掉换行符
.skip_adjust:
        sub rdx, 1              ; 去掉末尾的null终止符
        xor rcx, rcx            ; 清零目标缓冲区计数器        

_reverse_str:
        mov al, [rdi+rdx]       ; 从源字符串读取当前字符
        mov byte [rsi+rcx], al  ; 写入目标缓冲区
        inc rcx                 ; 目标计数器自增
        dec rdx                 ; 反向计数器自减
        jns _reverse_str        ; 当rdx >=0时继续循环(避免负数越界)

_reverse_end:
        mov byte [rsi+rcx], 0h  ; 给反转后的字符串添加null终止符
        mov rax, rsi            ; 返回目标缓冲区地址
        pop rbp
        ret

3. 修改调用方代码,提供可写缓冲区

在main中分配足够大小的可写缓冲区(可使用栈数组或动态分配):

#include <stdio.h>
#include <stdlib.h>
#include "prog.h"

#define BUF_SIZE 100

int main(void)
{
    char dest[BUF_SIZE];
    // 也可以用动态分配:char *dest = malloc(BUF_SIZE); 记得后续free
    printf("%s\n", asm_func4("Hello from asm_func4\n", dest));
    return 0;
}

额外注意事项

  • 调用约定匹配:x86-64系统下,函数参数依次存入rdi、rsi、rdx等寄存器,需确保汇编代码与C声明的参数顺序完全一致。
  • 边界检查:目标缓冲区的大小必须足够容纳反转后的字符串,避免缓冲区溢出。
  • strlen返回值逻辑:strlen返回的是字符串有效长度(不含末尾null终止符),计算索引时需注意不要越界访问源字符串。

内容的提问来源于stack exchange,提问作者Joao Pereira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 01:15:11