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

X86汇编项目求助:删除功能异常,输入任意索引仅删最后一项

X86汇编项目删除功能修复方案

你遇到的问题是:无论输入哪个索引,程序只会删除最后一个姓名。让我们一步步分析问题并修复:

问题分析

仔细查看你的sterge(删除)代码段,发现几个关键问题:

  1. numes变量未正确维护:在输入姓名的scrienume段中,每次添加新姓名后没有递增numes,导致这个记录姓名数量的变量始终为0,不仅逻辑不完整,还会导致无法通过姓名数量验证输入索引的有效性。
  2. 索引有效性判断不严谨:仅通过cmp ax, numePointer判断索引是否越界,没有结合当前实际的姓名数量,可能出现输入超过现有姓名数量的索引却未触发错误提示的情况。
  3. 错误提示字符串冗余:invalid字符串中多余的0会导致打印时出现空字符,影响错误信息的正常显示。

这些问题叠加可能导致你测试时出现“删除任何索引都只删最后一个”的错觉,我们可以通过以下修复确保逻辑完全正确:

修复步骤

  1. 维护numes变量:在scrienume段中,每次输入完一个姓名后添加inc numes,删除姓名时添加dec numes,正确记录姓名数量。
  2. 修正错误提示字符串:移除invalid字符串中多余的0,确保错误信息正常显示。
  3. 增强索引有效性验证:利用numes变量验证输入的0-based索引是否在[0, numes-1]范围内,避免无效索引的处理。
  4. 补充关键逻辑注释:为删除、遍历等核心步骤添加注释,方便后续维护和理解。

修改后的完整代码

.model small
.stack 100h

.data
indexul db 2 dup (0)
; 修复:移除多余的0,确保错误信息正常显示
invalid db "Indexul introdus este invalid!",'$'
string db 'Introduceti indexul numelui pe care doriti sa-l stergeti:',0,'$'
punct db '.$'
prompt db 'Introduceti un nume:',0,'$'
list db 'Lista cu numele este:',0,'$'
; 每个姓名占6字节(5字符+$),50个双字足够存储16个姓名
nume dw 50 dup(0)
numes dw 0  ; 记录当前姓名数量
numeIndex db 13, 10, 49, 46, 36  ; CR, LF, '1', '.', '$'

numePointer dw 50
menu db "Alege o optiune:",13,10
     db "1. Nume",13,10
     db "2. Lista cu numele",13,10
     db "3. Sterge un nume",13,10
     db "4. Exit",13,10,'$'

.code
start:
    mov al, 0
    ; 初始化数据段
    mov  ax, @data
    mov  ds, ax
    mov numePointer, offset nume
    call clear_screen
bucla:
    ; 换行
    mov dl, 0dh
    mov ah, 2
    int 21h
    mov dl, 0ah
    int 21h
    ; 显示菜单
    call display_menu
    mov ah, 1
    int 21h
    cmp al, '1'
    je scrienume
    cmp al, '2'
    je lista
    cmp al, '3'
    je sterge
    cmp al, '4'
    jmp exit
    jmp bucla

scrienume:
  mov  dx, offset prompt
  mov  ah, 09h
  int  21h
  mov  cx, 5
  mov  si, numePointer
read_char:
  mov  ah, 01h
  int  21h
  mov  [si], al
  inc  si
  loop read_char
  mov  byte ptr [si], '$'
  inc  si
  mov  numePointer, si ; numePointer += 6(5字符+$)
  inc numes ; 修复:递增姓名数量
  jmp  bucla

lista:
mov  byte ptr [numeIndex + 2], "1"
  mov  dx, offset nume
print_names:
  push dx                        ; 保存当前姓名的偏移地址
  mov  dx, offset numeIndex
  mov  ah, 09h
  int  21h
  inc  byte ptr [numeIndex + 2]  ; 递增序号("1"->"2"->...)
  pop  dx                        ; 恢复当前姓名的偏移地址

  mov  ah, 09h
  int  21h
  add  dx, 5 + 1 ; 移动到下一个姓名(每个姓名占6字节)
  cmp  dx, numePointer ; 检查是否遍历到最后一个姓名之后的地址
  jb   print_names
  jmp  bucla           ; 返回主循环

sterge:
    ; 提示用户输入要删除的姓名索引
    mov dx, offset string
    mov ah, 09h
    int 21h
    ; 读取用户输入的索引字符
    mov ah, 01h
    int 21h
    sub  al, 49      ; 将1-based输入转换为0-based索引("1"->0, "2"->1...)
    ; 验证索引是否在有效范围内(0 <= 索引 < numes)
    cmp al, 0
    jb invalidPosition
    mov ah, 0
    cmp ax, numes
    jnb invalidPosition
    
    mov  ah, 6
    mul  ah          ; AX = 索引 * 6,计算待删除姓名的起始偏移
    add  ax, offset nume
    mov  di, ax
    lea  si, [di + 6] ; SI指向待删除姓名的下一个姓名起始地址
    mov  cx, numePointer
    sub  cx, si       ; CX = 需要移动的字节数(从SI到numePointer的长度)
    cld               ; 设置方向标志为递增(SI和DI自增)
    rep movsb         ; 将后面的姓名往前移动,覆盖待删除的姓名
    mov  numePointer, di ; 更新numePointer为新的最后一个姓名之后的地址(DI移动后的值 = numePointer -6)
    dec  numes        ; 递减姓名数量
    jmp  bucla
  
invalidPosition:
    ; 显示错误信息
    mov dx, offset invalid
    mov ah, 09h
    int 21h
    jmp bucla

exit:
    ; 程序退出
    mov  ax, 4c00h
    int 21h

;---------------------------------------------
display_menu proc
  mov  dx, offset menu
  mov  ah, 9
  int  21h
  ret
display_menu endp

clear_screen proc
  mov  ah, 0
  mov  al, 3
  int  10H
  ret
clear_screen endp
end start

修复说明

  • numes变量维护:新增了姓名数量的增减逻辑,确保程序能准确跟踪当前的姓名总数。
  • 索引有效性增强:通过numes变量验证输入索引的合法性,避免处理超出范围的索引。
  • 错误字符串修正:移除冗余字符,保证错误信息清晰显示。
  • 逻辑注释补充:为核心操作添加注释,提升代码可读性和可维护性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:31:14