如何循环获取输入并打印结构体数组

问题描述 投票:0回答:2

我对如何循环遍历结构体数组来获取输入并存储它,然后打印结构体中的所有输入感到非常困惑。我有这段代码,我可以在其中手动访问数组的索引,并且它确实有效。

.model small
.stack 100h
.data
    Person struc
        name db 10 DUP(0)
        password db 10 DUP(0)
    Person ends

    people Person 10 DUP(<>)

    prompt db 'Enter your name: ', 0
    prompt2 db 13, 10, 'Enter password: ', 0
    res db 13, 10, 'Your name is: ', 0
    res2 db 13, 10, 'Your password is: ', 0
.code

include io.mac

main proc
    mov ax, @data
    mov ds, ax

    mov si, 0
    ; First person (index 0)
    PutStr prompt
    GetStr people[0].name
    PutStr prompt2
    GetStr people[0].password
    PutCh 0Ah

    ; Second person (index 1)
    PutStr prompt
    GetStr people[20].name
    PutStr prompt2
    GetStr people[20].password
    PutCh 0Ah

    ; Third person (index 2)
    PutStr prompt
    GetStr people[40].name
    PutStr prompt2
    GetStr people[40].password
    PutCh 0Ah

    ; Print first person's info (index 0)
    PutStr res
    PutStr people[0].name
    PutStr res2
    PutStr people[0].password
    PutCh 0Ah

    ; Print second person's info (index 1)
    PutStr res
    PutStr people[20].name
    PutStr res2
    PutStr people[20].password
    PutCh 0Ah

    ; Print third person's info (index 2)
    PutStr res
    PutStr people[40].name
    PutStr res2
    PutStr people[40].password
    PutCh 0Ah

    mov ax, 4C00h
    int 21h

main endp
end main

但问题是我不想手动输入所有这些,所以我尝试做一个循环以使事情变得更容易......但事实并非如此。这是我的代码:

.model small
.stack 100h
.data
    Person struc
        name db 10 DUP(0)
        password db 10 DUP(0)
    Person ends

    people Person 10 DUP(<>)

    prompt db 'Enter your name: ', 0
    prompt2 db 13, 10, 'Enter password: ', 0
    res db 13, 10, 'Your name is: ', 0
    res2 db 13, 10, 'Your password is: ', 0
.code

include io.mac

main proc
    mov ax, @data
    mov ds, ax

    mov cx, 3
    mov si, 0

    loop_input:
        PutStr prompt
        GetStr people[si].name
        PutStr prompt2
        GetStr people[si].password
        PutCh 0Ah

        add si, size Person ; size = 20
        loop loop_input

    mov cx, 3
    mov si, 0
    loop_output:
        PutStr res
        PutStr people[si].name
        PutStr res2
        PutStr people[si].password
        PutCh 0Ah

        add si, size Person ; size = 20
        loop loop_output


    mov ax, 4C00h
    int 21h

main endp
end main

这是我手动访问索引时的输出。

手动访问索引

这是我使用循环时的输出。 在此输入图片描述

assembly tasm
2个回答
0
投票

我在这两个代码中看到的唯一区别是 si 寄存器。在第一个代码中,您没有使用它,您使用值来访问内存地址。
我不知道 PutStr 和 GetStr 是如何实现的,可能在 io.mac 中,但似乎它们正在更改 si 寄存器.


0
投票

io.mac 中,GetStrPutStr 宏定义为:

GetStr  MACRO   string1, buffer_size, extra
   IFB     <string1>
     %OUT  ERROR: Missing string parameter in GetStr macro.
     EXITM
   ENDIF
 
   push    CX       ;; CX is used for buffer size
   IFB     <buffer_size>
     %OUT  WARNING: Missing string length parameter in GetStr macro.
     %OUT           Maximum string length of 80 is used.
     mov   CX,81    ;; 80 + 1 for CR
   ELSE
     mov   CX,buffer_size
   ENDIF

   IFNB    <extra>
     %OUT  WARNING: Redundant parameters in GetStr macro - ignored.
   ENDIF
  
   push    AX
   mov     AX,OFFSET string1
   call    proc_GetStr
   pop     AX
   pop     CX
   ENDM
PutStr  MACRO   string, extra
   IFB     <string>
     %OUT  ERROR: Missing string parameter in PutStr macro.
     EXITM
   ENDIF

   IFNB    <extra>
     %OUT  WARNING: Redundant parameters in PutStr macro - ignored.
   ENDIF
   
   push    AX
   mov     AX,OFFSET string
   call    proc_PutStr
   pop     AX
   ENDM

虽然我还没有看到 proc_GetStrproc_PutStr 中的内容,但看到甚至 AX 寄存器也被保留,我认为可以安全地假设所有寄存器最终都被保留。
让我担心的是他们在

mov AX,OFFSET string1
mov AX,OFFSET string
中使用了 OFFSET。这需要一个在汇编时已知的操作数。你的
people[0].name
没问题,但你的
people[si].name
不行,因为在组装时不知道 SI 寄存器将包含什么。如果使用这些宏
lea AX, string1
lea AX, string
你的程序可能会工作。

就个人而言,我会编辑 io.mac 文本文件并以这种方式解决它。


GetStr people[si].name
PutStr prompt2
GetStr people[si].password

您没有为 GetStr 指定可选的第二个宏参数。因为它默认为 81 并且考虑到您的字段仅限于 10 个字节,所以这样写会更安全:

GetStr people[si].name, 10
PutStr prompt2
GetStr people[si].password, 10
© www.soinside.com 2019 - 2024. All rights reserved.