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

汇编调用C加密函数实现字符串移位仅输出首字符的修复咨询

问题修复方案

核心错误点

  • 缓冲区分配过小:getMessage和encrypted仅分配了8字节(resq 1),无法存储普通长度的输入字符串,且长度定义len逻辑错误,没有正确获取输入字符串的实际长度
  • 字符偏移计算错误:字符串每个字符占1字节,代码中使用rcx*4作为偏移,每处理一个字符就向后跳4字节,只会读取到首字符,后续字符全部错位
  • 参数传递错误:调用encrypt时直接读取8字节内存到rdi,没有正确传递单字节字符;存储返回值时直接写入整个8字节rax,会破坏后续内存
  • 加密后的字符串没有添加字符串结束符\0,导致printf输出时无法正确识别字符串边界

修复后完整代码

extern printf, scanf
extern encrypt

global main

section .data
format db '%ld',0
format3 db "%s",10,0
format_str db "%s",0

message1:     db "1. Input New Message",10,0
message2:     db "Enter a number of shift:",10,0

section .bss
getMessage:     resb 1024    ; 分配1K缓冲区存储输入字符串
shiftNum        resq 1
encrypted       resb 1024    ; 分配1K缓冲区存储加密后字符串
str_len         resq 1       ; 存储输入字符串实际长度

section .text
main:
        mov rdx, message1
        call print

        call scanMessage
        mov [str_len], rax   ; 保存sys_read返回的实际输入长度
        dec qword [str_len]  ; 去掉sys_read读入的末尾换行符

        mov rdx, message2
        call print

        call scanChoice

        mov rdx, getMessage
        call print

        mov r8, getMessage
        mov rbx, [shiftNum]
        mov rdx, [str_len]
        call shift

        mov rdx, encrypted
        call print

        mov rax, 60
        mov rdi, 0
        syscall              ; 正常退出程序

; end main     

scanChoice:
        mov rdi, format
        mov rsi, shiftNum
        mov rax, 0
        call scanf
        ret

scanMessage:
        mov rax, 0
        mov rdi, 0
        mov rsi, getMessage
        mov rdx, 1024
        syscall
        ret

print:
        mov rdi,format3
        mov rsi,rdx
        mov rax,0
        call printf
        ret

shift:
        mov rcx, 0
loop:   cmp rcx, rdx
        jge done
        movzx rdi, byte [r8 + rcx] ; 仅读取1字节字符,零扩展到rdi
        mov rsi, rbx
        call encrypt
        mov byte [encrypted + rcx], al ; 仅保存返回的1字节加密字符
        inc rcx
        jmp loop
done:
        mov byte [encrypted + rcx], 0 ; 添加字符串结束符
        ret

改动说明

  1. 扩大了输入、输出缓冲区到1024字节,新增变量存储输入字符串的实际长度,去掉了sys_read读取的末尾换行符
  2. 移除了偏移地址的*4计算,按单字节1单位偏移读取、存储字符
  3. 用movzx指令读取单字节字符传递给encrypt,返回时仅存储rax低8位的al寄存器(即加密后的字符)
  4. 加密结束后在字符串末尾补\0,保证printf可以正常输出完整字符串
  5. 新增正常退出程序的系统调用,避免程序执行结束后段错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 04:54:03