汇编实验7,关于bx,si,di,选择数据的不同而导致的死循环,不知道如何解决
这个是我的答案:发生了死循环{:5_100:}assume cs:code,ds:data,es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995';84(0~53H)
;21年的21个字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000.4649000,5937000
;21年公司总收入的21个dword型数据;84(54H~0A7H)
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226;84;错误是42,前面一共210
dw 11542,14430,15257,17800;(0A8H~0D1H)
;21年雇佣人数的21个word型数据
data ENDS
;存放数据
table segment
db 21 dup('year summ ne ?? ')
table ENDS
code segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0 ;控制行
mov si,0 ;控制双字型数据
mov di,0 ;控制字型数据
mov cx,21
s: mov ax,;年份
mov dx,
mov es:,ax
mov es:,dx;输入年份
mov ax,;工资
mov dx,
mov es:,ax
mov es:,dx
div word ptr ds:
mov word ptr es:,ax
mov ax,;人数
mov es:,ax;输入人数
add bx,16
add si,4
add di,2
loop s
mov ax,4C00H
int 21H
code ends
end start
这个是参考答案:正常运行{:5_99:}
assume cs:code,ds:data,es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0 ;控制双字型
mov si,0 ;控制行
mov di,0 ;控制字型
mov cx,21
s: mov ax,
mov es:,ax
mov ax,.2
mov es:.2,ax
mov ax,.84
mov es:.5,ax
mov dx,.86
mov es:.7,dx
div word ptr ds:.168
mov es:.13,ax
mov ax,.168
mov es:.10,ax
add di,2
add bx,4
add si,16
loop s
mov ax,4c00h
int 21h
code ends
end start
看得出来,你在这份汇编代码里遇到了一些困惑!有时候,程序就像一个顽皮的小鱼,游来游去不肯安分,导致死循环的出现。别担心,我会用轻松幽默的方式来帮你捋清楚这段代码!
首先,我们要明白,汇编语言里的每一步都非常重要,就像调味料在一道菜里的作用。只要你稍微多放或少放个什么,小鱼就可能游得不对劲了。
### 死循环的可能原因:
1. **行计数不正确**:
你的代码里设置 `mov cx, 21`,这表示循环21次,但如果你没有正确更新 bx、si、di 的值,可能会导致循环条件变得不符合,造成无限循环。在你的参考答案中,这些值都是在正确的地方更新的。
2. **内存访问错误**:
确保你在整个程序中使用的内存地址都是有效的。如果某个地址越界了,程序就可能会陷入循环。
3. **数据选择不当**:
你提到使用 `bx`, `si`, `di` 不同的选择数据导致的问题。确保每次选择数据时,它们确实指向了数据段中的有效位置,而不是空洞的位置。例如,在你的代码中,使用 `add si, 4` 来增加双字型索引,而在参考答案里是 `add si, 16` 可能就是这种差异,让小鱼选择了错误的数据。
### 解决方案提示:
- **确认数据结构**:检查你的数据定义,确保你的字符串、DWORD 和 WORD 数据是按照预期的顺序和大小排列。这可以避免因数据读取错误导致的死循环。
- **逐步调试**:你可以在每次循环的开始处添加一些断点,确认 bx、si、di 的值是否如你所愿地增长。这就像投喂小鱼之前先检查鱼粮是否足够。
- **输出调试信息**:在循环内,可以用 `int 21H` 进行简单的打印,以显示当前的 bx、si、di 值,帮助你判断程序执行到了哪个位置。
下面是你的代码中一点点修改的示例,确保它能更流畅地运行,并且不会让你的小鱼游进死胡同:
s:
mov ax, ds: ; 读取年份
mov es:, ax ; 存储年份
mov ax, ds: ; 读取工资
mov es:, ax ; 存储工资
mov ax, ds: ; 读取人数
mov es:, ax ; 存储人数
; 假设这里是进行除法处理,确保上下文的正确性
div word ptr ds: ; 注意确保 si 与操作数的相对位置关系
; 更新索引,增量要相符
add bx, 16
add si, 4
add di, 2
loop s
希望这些建议能帮到你,让你的汇编小鱼顺利游出困境!编程的乐趣就在于解谜,加油,有问题随时来问哦!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 参考答案:
assume cs:code,ds:data,es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0 ;控制双字型
mov si,0 ;控制行
mov di,0 ;控制字型
mov cx,21
s: mov ax,
mov es:,ax
mov ax,.2
mov es:.2,ax
mov ax,.84
mov es:.5,ax
mov dx,.86
mov es:.7,dx
div word ptr ds:.168
mov es:.13,ax
mov ax,.168
mov es:.10,ax
add di,2
add bx,4
add si,16
loop s
mov ax,4c00h
int 21h
code ends
end start
不知道为什么乱码了:
assume cs:code,ds:data,es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start:mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0 ;控制双字型
mov si,0 ;控制行
mov di,0 ;控制字型
mov cx,21
s: mov ax,
mov es:,ax
mov ax,.2
mov es:.2,ax
mov ax,.84
mov es:.5,ax
mov dx,.86
mov es:.7,dx
div word ptr ds:.168
mov es:.13,ax
mov ax,.168
mov es:.10,ax
add di,2
add bx,4
add si,16
loop s
mov ax,4c00h
int 21h
code ends
end start
GUNDAM_00 发表于 2024-08-10 17:49
参考答案:
assume cs:code,ds:data,es:table
dat ...
看起来你想对参考答案进行一些分析。让我们一起把这段汇编代码过一遍,像个侦探一样寻找可能的“死循环”原因。
### 代码解读:
1. **数据段 `data segment`**:
- 这里定义了一串数据,包括年份(字符串)、收入(双字)、雇佣人数(字)。确认这些数据都是按照正确的数据类型和大小排列是很重要的。
2. **存放数据的表 `table segment`**:
- 用于存储结果的地方,这里用 `db 21 dup ('year summ ne ?? ')` 定义了一个可重复的字符串格式。确保它足够大以容纳所有的信息。
3. **代码段 `code segment`**:
- 主要执行的代码部分。
### 核心逻辑:
- **初始化寄存器**:
mov bx,0 ; 控制双字型
mov si,0 ; 控制行
mov di,0 ; 控制字型
mov cx,21 ; 循环次数
- **循环体 `s:`**:这里是核心逻辑处理部分。
- `mov ax, ...` 从数据段读取年份、工资和人数,并将其存入 ES 段。
- `div` 指令用于执行除法运算,结果存储在 AX 中,最后再写回到 ES 段。
- 通过 `add` 指令更新 `bx`, `si`, 和 `di` 的值,用于控制数据的索引。
### 注意事项与潜在问题:
1. **内存地址访问**:
- 确保在使用 `mov es:,` 和 `div` 指令时,所使用的内存地址是有效的,不然你的小鱼可能会游错方向导致死循环。
2. **寄存器增量**:
- 依据参考答案,`add bx, 4` 是用于跟踪双字数据,而 `add si, 16` 是用于跟踪字符串数据,保证每次循环都在正确位置不要越界。
- 如果没有正确更新你使用的索引,程序将一直指向同一个位置,造成死循环。
3. **调试输出**:
- 在循环体内加入一些打印指令,比如使用 DOS 中断 `int 21h` 来输出来监控当前 `bx`, `si`, `di` 的状态,能帮助你发现问题。
### 总结:
如果你还是觉得有些迷茫,建议逐步调试代码,观察每一步的执行效果,看看哪些地方可能出错。记住,编程就像钓鱼,有时候需要耐心等待和不断尝试,才能钓到大鱼!如果还有其他问题,或者需要进一步的帮助,随时告诉我哦!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 本帖最后由 jackz007 于 2024-8-10 23:17 编辑
这里有错误:
dd 345980,590827,803530,1183000,1843000,2759000,3753000.4649000,5937000
红颜色的句点应该是一个逗号。
只要改掉这个错误,这个代码没有任何的问题。如果说改进,那么,最需要改进的地方是应该为代码添加堆栈段
assume cs:code,ds:data,es:table
stack segment stack ; 添加
db 400H dup(0) ;添加
stack ends ; 添加
data segment
. . . . . .
jackz007 发表于 2024-8-10 20:39
这里有错误:
dd 345980,590827,803530,1183000,1843000,2759000,3753000.4649000,5937000
...
哥们,我终于可以运行了,感谢感谢感谢感谢感谢感谢{:5_110:}{:5_95:}{:5_101:}
页:
[1]