assembly 我的代码需要将我的输入存储在一个数组中,然后显示它们,但它只显示我最后的输入,而不是所有的输入,我该如何解决这个问题?

icomxhvb  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(119)

当我在键盘上按1时,我需要输入更多的5个字符的名称,将它们存储在一个数组中,当我按2时,它应该显示我写的所有名称。唯一的问题是,当我按2时,只有姓氏显示。我认为它们相互覆盖,但我找不到原因。有人能帮忙吗?下面是应该存储名称的代码:

scrienume:
    ; print prompt
    mov dx, offset prompt
    mov ah, 9
    int 21h
    ;Read the input string one character at a time
    mov cx, 5
    mov si, offset nume
read_char:
    mov ah, 1
    int 21h
    cmp al, 0ah ; check if input character is newline
    je end_of_string
    mov [si], al ; store input character in array
    inc si
    loop read_char
end_of_string:
    mov byte ptr [si], '$' ; add null terminator
    jmp bucla

下面是显示它们的代码:

lista:
    mov si, offset nume ; move offset of names array to si
    print_names:
        mov dx, si ; move contents of si (memory location of name) to dx
        mov ah, 9 ; print string function
        int 21h ; call MS-DOS function
        add si, 5 ; increment si to next memory location
        cmp byte ptr [si], '$' ; check if the current name is the last one
        jne print_names ; if not, repeat
    jmp bucla ; return to main loop

我试图将每个名称存储在一个数组中,但是它们相互覆盖,所以我的程序没有显示所有的输出。

x8goxv8g

x8goxv8g1#

* 脚本 * 中的错误

  • 如果 nume 是5个字符的名字数组的地址,那么你只能使用这个地址来输入第一个名字,输入第二个名字时,你应该把SI初始化为nume + 6,第三个名字的初始化为nume + 12,以此类推......每次都要多输入6,因为你存储了5个字符和1个$符号。
  • 如果你允许输入循环提前退出(cmp al, 0ahje end_of_string),你将失去每个数据6字节的设置。顺便说一句,在DOS下你需要检查13,看看是否有一个换行符。

* 列表 * 中出错

这段代码将只显示第一条记录!add si, 5指令将移动到一个确实有$符号的位置,您的代码将注意到这个位置,后面跟着 not 重复循环。
由于输入循环中的覆盖问题,显示第一条记录时会显示姓氏。

这是一个可行的解决方案

定义一个字长的变量,它将保存数组中当前记录的地址。

mov  numePointer, offset nume

  ...

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  dx, offset nume
print_names:
  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

(*)为了提高输出的可读性,您可能需要插入一个换行符:

push dx
  mov  dl, 13          ; carriage return
  mov  ah, 02h
  int  21h
  mov  dl, 10          ; linefeed
  mov  ah, 02h
  int  21h
  pop  dx

相关问题