assembly 解决我上一个项目的问题https://stackoverflow.com/q/75151982/21022612

djp7away  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(132)

关于我在汇编x86中做的最后一个项目,代码工作得很好,但我尝试了一些东西,我发现如果我只输入一个名称,并试图删除它,它不起作用,而且如果我在列表中输入超过10个名称,索引显示不正确。
我试着自己指出这个问题,但我想不出来。
你们能告诉我问题出在哪里吗?或者我应该在哪里做些改变?
代码:

.model small
.stack 100h

.data
indexul db 2 dup (0)
invalid db "Indexul introdus este invalid!",0,'$'
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,'$'
nume dw 50 dup(0)
numes dw 0
numeIndex db 13, 10, 49, 46, 36

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
    ;INITIALIZE DATA SEGMENT.
    mov  ax, @data
    mov  ds, ax
    mov es, ax
    mov numePointer, offset nume
    call clear_screen
bucla:
    ;Move cursor to the next line
    mov dl, 0dh
    mov ah, 2
    int 21h
    mov dl, 0ah
    int 21h
    ;Display menu
    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

    mov dx, offset numePointer

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
  jmp  bucla




lista:
mov  byte ptr [numeIndex + 2], "1"
  mov  dx, offset nume
print_names:
  push dx                        ; (1)
  mov  dx, offset numeIndex
  mov  ah, 09h
  int  21h
  inc  byte ptr [numeIndex + 2]  ; "1" -> "2" -> "3" ...
  pop  dx                        ; (1)

  mov  ah, 09h
  int  21h
  add  dx, 5 + 1
  cmp  dx, numePointer ; check if the current name is the last one
  jb   print_names
  jmp  bucla           ; return to main loop


sterge:
    ; Prompt user for position of name to delete
    mov dx, offset string
    mov ah, 09h
    int 21h
    ; Read position from user
    mov ah, 01h
    int 21h
     sub  al, 49      ; AL=["1","9"] 1-based input -> AL=[0,8] 0-based index
  mov  ah, 6
  mul  ah          ; -> AX = {0,6,12,18,24,30,36,42,48}
  add  ax, offset nume
  cmp  ax, numePointer
  jnb  invalidPosition
  mov  di, ax
  lea  si, [di + 6]
  mov  cx, numePointer
  sub  cx, si
  cld
  rep movsb
  mov  numePointer, di
  dec  numes
  jmp  bucla
  
invalidPosition:
    ; Display error message
    mov dx, offset invalid
    mov ah, 09h
    int 21h
    jmp bucla



exit:
    ;FINISH PROGRAM.
    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
6fe3ivhb

6fe3ivhb1#

nume dw 50 dup(0)

与其使用dw,不如使用db来实现这一点,该程序被设想为最多处理9个五字符名称,因此这应该是nume db 54 dup(0)
我之前的回答已经提到了这一点!
一个一个一个一个
(1)和(3)是多余的。必须从程序中删除这些行。
(2)是一个错误。您需要条件跳转je exit
我尝试somting并且我发现如果我输入仅仅一个名字并且尝试删除它,它不工作
在这个程序中,正如这里所介绍的,我没有发现不能从列表中删除最后一个剩余名称的任何指示。
而且如果我在列表中输入超过10个名字,索引就不能正确显示。
这个程序最多可以处理9个五字符的名字,这就是为什么我们包含了numeIndex db 13, 10, 49, 46, 36这样的行,它只能显示一个十进制数字。
下面是我的改编版本,可以容纳99个名字。我想说已经足够了。你能想出那么多有意义的五个字符的名字吗?

nume       db 594 dup(0)
numeIndex  db 13, 10, " 0.$"

  ...

lista:
  mov  word ptr [numeIndex + 2], 3020h ; Reset it to " 0"
  mov  dx, offset nume
print_names:
  mov  ax, word ptr [numeIndex + 2]
  inc  ah                        ; "0" -> "1" -> "2" ...
  cmp  ah, "9"
  jbe  NoCarry
  mov  ah, "0"
  cmp  al, " "
  jne  JustInc
  mov  al, "0"
JustInc:
  inc  al                        ; "0" -> "1" -> "2" ...
NoCarry:
  mov  word ptr [numeIndex + 2], ax

  push dx                        ; (1)
  mov  dx, offset numeIndex
  mov  ah, 09h
  int  21h
  pop  dx                        ; (1)

  ...

相关问题