MASM汇编中如何通过循环实现结构体数组的输入、存储与内容打印?
MASM汇编中如何通过循环实现结构体数组的输入、存储与内容打印?
嘿,我完全懂你现在的烦恼——手动挨个写结构体数组的索引不仅繁琐,要是数组元素多了还容易出错。咱们把这段代码改成循环版本,不管要处理多少个Person,代码都能简洁复用,效率也更高~
首先先理清楚关键信息:你定义的Person结构体里,name占10字节,password也占10字节,所以每个结构体总共是20字节,这就是咱们循环里每次要偏移的步长。不过MASM提供了sizeof运算符,能自动计算结构体大小,比手动写20更靠谱,以后修改结构体成员时也不用手动调整这个数值。
下面是修改后的完整代码,我会逐段给你解释:
.model small .stack 100h .data Person struc name db 10 DUP(0) password db 10 DUP(0) Person ends ; 定义结构体数组,共10个元素 people Person 10 DUP(<>) ; 定义要处理的人数,方便修改 num_people equ 3 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 ; ===== 输入循环:处理num_people个用户 ===== mov cx, num_people ; cx作为循环计数器,设置为要处理的人数 mov si, 0 ; si指向当前结构体的起始地址,初始为第一个元素 input_loop: PutStr prompt GetStr [si].Person.name ; 读取当前结构体的name字段 PutStr prompt2 GetStr [si].Person.password ; 读取当前结构体的password字段 PutCh 0Ah ; 换行,让输入界面更整洁 add si, sizeof Person ; 移动si到下一个结构体的起始地址 loop input_loop ; cx自动减1,不为0就回到input_loop继续循环 ; ===== 打印循环:输出所有用户的信息 ===== mov si, 0 ; 重置si,回到第一个结构体的起始地址 mov cx, num_people ; 重置计数器 print_loop: PutStr res PutStr [si].Person.name ; 打印当前结构体的name PutStr res2 PutStr [si].Person.password ; 打印当前结构体的password PutCh 0Ah ; 换行分隔不同用户的信息 add si, sizeof Person ; 移动到下一个结构体 loop print_loop ; 循环直到所有信息都打印完 ; 退出程序 mov ax, 4C00h int 21h main endp end main
关键细节说明:
- 循环计数器
cx:在MASM里常用cx作为循环计数器,loop指令会自动将cx减1,若结果不为0则跳转到指定标签,完美适配咱们的循环需求。 - 结构体指针
si:si寄存器用来指向当前操作的Person结构体,每次循环通过add si, sizeof Person移动到下一个元素,避免了手动计算偏移量(比如你之前写的20、40)。 sizeof Person运算符:MASM的内置运算符,会自动计算Person结构体的总字节数,即使以后修改name或password的长度,这部分代码也不用改动。- io.mac宏:你用到的
PutStr、GetStr、PutCh都是io.mac里的宏,只要确保ds指向数据段(你已经通过mov ax,@data和mov ds,ax完成了这一步),就能正常工作。
如果需要处理全部10个结构体元素,只要把num_people equ 3改成num_people equ 10就行,完全不用修改循环逻辑,是不是方便多了?
备注:内容来源于stack exchange,提问作者Carl Angelo
相关产品推荐
相关产品推荐

