MASM汇编任务逻辑理解及代码问题咨询(DOS环境)
汇编任务说明(基于MASM 5.00、DOS环境)
给定的逻辑段
I1 db ? I2 db ? I3 db ? A1 dw 5 dup (6 dup (0fh,4 dup (0))) Data1 ends
任务要求:
- 创建代码段
Code1,使用索引I1、I2、I3将三维数组A1中值为0fh的字替换为后续5个字的和; - 创建数据段
Data2,定义A2 dw 5 dup (6 dup (0fh,4 dup (0))); - 创建代码段
Code2,用串指令完成步骤1的任务,随后比较A1与A2,并实现从Code1到Code2的间接段间转移。
注:适配MASM 5.00编译器与DOS环境
;for MASM 5.00 translator ;for DOS .386 .MODEL flat ; for MASM 5.00
用户编写的代码
.386 Data1 segment I1 db ? I2 db ? I3 db ? A1 dw 5 dup (6 dup (0fh,4 dup (0))) Data1 ends Data2 segment A2 dw 5 dup (6 dup (0fh,4 dup (0))) Data2 ends Code1 segment use16 assume cs:Code1, ds:Data1 start: mov [I1], 0 mov [I2], 0 mov [I3], 0 mov ax, DATA1 mov ds, ax L1: L2: L3: movzx ax, byte ptr [I1] imul bx, ax, 6*5*2 movzx ax, byte ptr [I2] imul ecx, ax, 5*2 xor esi,esi movzx ax, byte ptr [I3] mov si, ax lea di, [ecx + esi*2] cmp A1[bx+di],0fh jne NEXT mov ax,0 add ax,[A1+bx+di+2] add ax,[A1+bx+di+4] add ax,[A1+bx+di+6] add ax,[A1+bx+di+8] add ax,[A1+bx+di+10] mov [A1+bx+di],ax NEXT: inc I3 cmp I3, 5 jle L3 mov I3, 0 inc I2 cmp I2, 6 jle L2 mov I2, 0 inc I1 cmp I1, 5 jle L1 jmp far ptr start2 Code1 ends Code2 segment use16 assume cs:Code2, ds:Data1, es:Data2 start2: mov ax,data1 mov ds,ax mov ax,data2 mov es,ax mov cx, 150d mov di, OFFSET A2 mov ax, 0fh cld L: repnz scasw sub di, 2 xor dx,dx add dx,[A2+di+2] add dx,[A2+di+4] add dx,[A2+di+6] add dx,[A2+di+8] add dx,[A2+di+10] mov [A2+di],dx add di, 2 dec cx cmp cx,0 jg L mov si,OFFSET A1 mov di,OFFSET A2 cld repz cmpsw sub si, 2 sub di, 2 mov bx,A1[si] mov dx,A2[di] mov ax, bx sub ax, dx mov ax,4c00h int 21h Code2 ENDS end start2
代码逻辑分析与问题修正
任务核心逻辑拆解
先明确三维数组A1/A2的结构:
- 外层:5个元素(对应
I1,索引0~4) - 中层:每个外层元素包含6个单元(对应
I2,索引0~5) - 内层:每个单元是
(0fh, 4 dup (0)),即1个0fh字 + 4个0字,共5个字,数组总长度为5*6*5=150个字。
任务核心:找到数组中所有值为0fh的字,将其替换为该位置后方连续5个字的和。
Code1的问题点
- 循环条件错误:
I3从0开始循环,对应内层5个元素,应循环到I3=4,但代码中cmp I3,5jle L3会导致I3=5时仍进入循环,触发索引越界;同理I2应循环到5而非6,I1应循环到4而非5。
- 段间转移不符合要求:
任务要求实现间接段间转移,代码中jmp far ptr start2是直接远转移,需改为间接方式,例如在Data1中定义转移地址,再通过寄存器跳转:; 在Data1段添加 JumpAddr dd offset start2 dw Code2 ; 在Code1末尾替换原跳转指令 mov eax, JumpAddr jmp eax - 寄存器使用冗余:
使用32位寄存器ecx在DOS 16位环境下无必要,换成16位寄存器cx即可,避免兼容性问题。
Code2的问题点
- 串指令循环逻辑错误:
repnz scasw会自动递减cx,代码中额外执行dec cx会导致循环提前终止,需删除该语句,循环条件改为jnz L(当cx未减至0时继续查找)。 - 数组比较后的逻辑冗余:
repz cmpsw执行后,若cx=0说明A1与A2完全匹配,当前代码仅获取第一个不相等的元素,可根据cx值直接判断是否匹配,无需额外取值计算。
修正后的核心逻辑提示
- 调整Code1的循环条件:
cmp I3,4、cmp I2,5、cmp I1,4; - 将Code1的直接远转移改为间接段间转移;
- 删除Code2中手动
dec cx的语句,调整循环判断逻辑; - 注意:原数组每个
0fh后方仅4个0字,任务要求的“后续5个字”会触发越界,需确认任务是否存在数组定义笔误,或按任务要求强制处理越界访问。
内容的提问来源于stack exchange,提问作者ex4mple
相关产品推荐
相关产品推荐

