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

x86汇编encryptStr字符串加密函数实现代码合理性咨询

问题结论

你提交的代码完全不符合题目要求,没有实现任何题目指定的加密和统计逻辑,属于功能完全错位的实现,具体问题清单如下:

  • 基础命名错误:题目要求实现的函数名为encryptStr,你的代码里拼写为encriptStr,链接时会找不到对应符号
  • 核心逻辑完全偏离:你写的是九进制字符串转整数的乘法计算逻辑,既没有实现「字母字符加1、非字母保持不变」的加密规则,也没有实现三个指定指标的统计
  • 未定义内存引用:代码中使用了rSum、digit两个未在.data/.bss段声明的内存标签,运行时会触发段错误直接崩溃
  • 参数处理不全:按照x86-64 System V标准调用约定,函数的四个参数依次存放在rdi(inStr)、rsi(ltrCnt地址)、rdx(digitCnt地址)、rcx(strLen地址),你的代码只使用了前两个参数,后两个统计值的地址完全没处理
  • 循环逻辑错误:遍历字符时只处理'0'和'1',遇到其他任意字符直接跳出循环,根本无法遍历完整个NULL结尾的字符串
  • 数据长度不匹配:题目明确要求三个统计值是无符号双字(32位),你的代码往对应地址写入64位qword,会造成相邻内存的越界覆写
  • 未处理初始值要求:题目明确说明传入的三个计数变量未初始化为0,你的代码没有先给这三个变量置0再计数,统计结果完全不可控
  • 存在无效代码:函数末尾多写了一个永远执行不到的ret指令,还存在重复赋值r11寄存器的无效操作

符合要求的实现参考

本实现不需要额外的全局/静态内存变量,所有计数都用寄存器暂存,遍历完成后统一写回参数地址,无多余内存访问,效率符合要求。

寄存器使用规划(遵循调用约定规则)

仅对用到的被调用者保存寄存器做入栈/出栈恢复:

  • rbx:暂存输入字符串首地址
  • r12:暂存字母计数
  • r13:暂存数字计数
  • r14:暂存遍历偏移/字符串总长度
  • rax:临时存放当前读取的字符

r10、r11、rax属于调用者保存寄存器,函数内无需额外做保存恢复操作。

逻辑说明

  1. 进入函数后暂存传入的参数地址,同时将三个计数寄存器初始化为0
  2. 逐字节读取字符串字符:
    • 遇到NULL字符时终止遍历
    • 总长度计数直接+1
    • 判断字符是否为大写字母(A`Z`)或小写字母(`a`z):是则字母计数+1,字符值加1后写回原位置(和题目示例一致,Z/z加1后直接变为[/{,不需要做回绕到a/A的处理)
    • 否则判断是否为数字(0~9):是则数字计数+1,字符保持不变
    • 其余字符直接跳过,不修改、不额外计数
  3. 遍历结束后,把三个计数值分别写入对应参数指向的32位内存地址,恢复保存的寄存器后返回

对应汇编代码

; 函数实现:encryptStr
; 参数遵循x86-64 System V调用约定:
; rdi = inStr 输入字符串首地址
; rsi = ltrCnt 字母计数变量地址(32位无符号)
; rdx = digitCnt 数字计数变量地址(32位无符号)
; rcx = strLen 字符串长度变量地址(32位无符号)
global encryptStr
encryptStr:
    ; 保存用到的被调用者保存寄存器
    push rbx
    push r12
    push r13
    push r14

    ; 暂存参数、初始化计数为0
    mov rbx, rdi        ; 存字符串首地址到rbx
    xor r12, r12        ; r12 = 字母计数,初始0
    xor r13, r13        ; r13 = 数字计数,初始0
    xor r14, r14        ; r14 = 遍历偏移/字符串总长度,初始0

loop_start:
    mov al, byte [rbx + r14]   ; 读取当前字符
    test al, al                ; 判断是否为NULL结尾
    jz loop_end

    inc r14                    ; 总长度+1(已确认当前字符不是NULL,不计入结尾符)

    ; 判断是否为字母
    cmp al, 'A'
    jb check_digit             ; ASCII码小于'A',跳去判断是不是数字
    cmp al, 'Z'
    jbe is_letter              ; 在'A'~'Z'区间,是大写字母
    cmp al, 'a'
    jb check_digit             ; 大于'Z'小于'a',不是字母,跳去判断数字
    cmp al, 'z'
    jbe is_letter              ; 在'a'~'z'区间,是小写字母
    jmp next_char              ; 大于'z',不是字母数字,直接处理下一个字符

is_letter:
    inc al                     ; 字母执行加1加密
    mov byte [rbx + r14 - 1], al ; 写回加密后的字符(r14已经自增,偏移减1定位到当前字符位置)
    inc r12                    ; 字母计数+1
    jmp next_char

check_digit:
    cmp al, '0'
    jb next_char               ; ASCII码小于'0',不是数字
    cmp al, '9'
    ja next_char               ; ASCII码大于'9',不是数字
    inc r13                    ; 数字计数+1

next_char:
    jmp loop_start

loop_end:
    ; 把三个计数写回对应地址,使用32位寄存器操作匹配无符号双字要求
    mov [rsi], r12d            ; 写入字母计数
    mov [rdx], r13d            ; 写入数字计数
    mov [rcx], r14d            ; 写入字符串总长度

    ; 恢复保存的寄存器
    pop r14
    pop r13
    pop r12
    pop rbx
    ret

你原来写的printString函数逻辑正确,可以直接保留使用,调用时注意修正函数名拼写错误即可。用题目给出的测试用例Hello Zoo 12验证,加密后输出为Ifmmp [pp 12,三个统计值分别为字母数8、数字数2、总长度12,完全符合题目要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:09:20