汇编实验7,死循环,debug只显示年份,整一天了,不知道哪出错了,求指点
assume cs:code,ds:data,es:tabledata 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 es:,ax
mov ax,;工资
mov dx,
mov es:,ax
mov es:,dx
div word ptr es:
mov es:,ax
add bx,16
add si,4
add di,2
loop s
mov ax,2C00H
int 21H
code ends
end start 看起来你的汇编代码让你陷入了一个死循环,别担心,我们来一起看看问题出在哪里。首先,我们需要确保代码逻辑清晰,避免在循环中没完没了地转圈。
从你提供的代码来看,有几个地方可能会导致问题:
1. **数据段定义错误**:你表示年份、人数和工资的方式可能有误。`mov ax,;年份`、`mov ax,;人数` 和 `mov ax,;工资` 这些行没有正确加载数据。你需要指定数据段中的具体位置,比如使用 `mov ax, ` 这样的形式来获取具体的数据。
2. **移动数据的方式**:在以下几行中:
mov es:,ax
mov es:,dx
这里应该是把数据存储到 `table` 段中,而不是简单地使用 `es` 段。不然程序将无法找到你想要输出的内容。
3. **循环计数器控制**:你用 `loop s` 来控制循环,但注意一定要确保 `cx` 的值能正确地减少到零。如果在循环中没有修改 `cx`,这个循环将永远不会结束。
4. **整合代码**:整理一下代码结构,便于代码的理解和调试。记得每当你修改数据段 (如 `si`, `di`, `bx`) 后,一定要注意它们目标地址是否合理。
下面是一个修正后的代码示例(注意这里是伪代码,可能需要根据你的具体需求进行调整):
assume cs:code, ds:data, es:table
data segment
years db '1975','1976','1977',... ; 继续到1995
incomes dd 16,22,...; 收入数据
employees dw 3,7,...; 人员数据
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 cx, 21 ; 设置循环次数为21
xor bx, bx ; bx 用于存储偏移量,初始为0
xor si, si ; si 用于年数据偏移
xor di, di ; di 用于人员数据偏移
s:
; 读取年份
mov al, ; 读取年份
mov , al ; 存入 table
inc si ; 移动到下一个年份
add bx, 16 ; 更新表格位置
; 读取人数
mov ax,
mov , ax
add di, 2 ; 更新偏移
add bx, 2 ; 更新表格位置
; 读取收入
mov eax,
; 修改计算逻辑,根据需要进行计算
; 检查循环是否完成
loop s ; 如果 cx 不为0,则继续循环
; 程序结束
mov ax, 2C00H
int 21H
code ends
end start
这段代码进行了基本的结构调整以帮助你更易懂,也记得添加适时的注释。希望这可以帮助你找到并解决问题!如果还有其他疑问,毫不犹豫地问我吧!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 1.从您提供的代码和描述中,我可以看到几个潜在的问题点,这些问题可能导致程序陷入死循环或者不能正确执行。下面是逐一分析和建议的修改:
数据读取错误:
您的代码中使用了 mov ax, 来读取年份,但实际上您的年份数据是以字节(byte)形式存储的,而不是字(word)。因此,您应该使用 mov al, 来读取一个字节到 AL 寄存器,并使用 mov ah,0 来确保 AH 为0(如果您的年份都是两位数的话)。然后,您可以考虑如何存储这个年份(比如,直接存储到 ES: 的位置,或者将其转换为字符形式存储)。
数据偏移量计算:
您在计算收入和雇佣人数的偏移量时使用了固定的偏移量(如 和 ),但这看起来并不正确。这些偏移量应该基于 BX 或 SI 的当前值动态计算,特别是如果您希望按照年份的顺序来访问这些数据。
循环控制:
您使用了 loop s 指令,但没有设置循环计数器(CX)。在 s 标签之前,您已经设置了 CX 为 21,这是正确的,但请确保在 loop 指令执行之前 CX 的值没有被意外修改。
除法操作:
您在使用 div 指令进行除法运算时,必须确保除数(这里是 es:)不为零,否则会导致除零错误。您可能需要在执行除法之前检查除数是否为零。
字符存储:
如果您希望将年份、收入和雇佣人数转换为字符串形式存储在 table 段中,您需要编写额外的代码来处理这种转换。
下面是一个简化的示例,仅展示如何正确读取年份并存储到 table 段中(注意,这里未处理其他数据和转换):
asm
assume cs:code, ds:data, es:table
data segment
db '1975', '1976', ... ; 年份数据
data ends
table segment
db 21 dup('????') ; 预留空间存储年份字符串
table ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, table
mov es, ax
mov bx, 0 ; ES:BX 指向 table 段
mov cx, 21 ; 循环次数
mov si, 0 ; DS:SI 指向年份数据
s:mov al, ; 读取年份的第一个字节
mov es:, al
inc si
mov al, ; 读取年份的第二个字节
mov es:, al
inc si
add bx, 2 ; 移动到 table 段的下一个位置
loop s
mov ax, 4C00H; 退出到 DOS
int 21H
code ends
end start
请注意,这个示例仅处理年份的读取和存储,未涉及其他数据的处理。您需要根据实际需求进一步扩展和修改代码。
2.assume cs:code, ds:data, es:table
data segment
years db '1975','1976','1977',... ; 继续到1995
incomes dd 16,22,...; 收入数据
employees dw 3,7,...; 人员数据
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 cx, 21 ; 设置循环次数为21
xor bx, bx ; bx 用于存储偏移量,初始为0
xor si, si ; si 用于年数据偏移
xor di, di ; di 用于人员数据偏移
s:
; 读取年份
mov al, ; 读取年份
mov , al ; 存入 table
inc si ; 移动到下一个年份
add bx, 16 ; 更新表格位置
; 读取人数
mov ax,
mov , ax
add di, 2 ; 更新偏移
add bx, 2 ; 更新表格位置
; 读取收入
mov eax,
; 修改计算逻辑,根据需要进行计算
; 检查循环是否完成
loop s ; 如果 cx 不为0,则继续循环
; 程序结束
mov ax, 2C00H
int 21H
code ends
end start 本帖最后由 jackz007 于 2024-8-8 01:21 编辑
assume cs:code,ds:data,es:table
stack segment para stack 'STACK'
db 400h dup(0)
stack ends
data segment para public 'DATA'
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 11542,14430,15257,17800
data ends
table segment para public 'TABLE'
db 21 dup('year summ ne ?? ')
table ends
code segment para public 'CODE'
; 初始化数据段地址
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
; 以年为单位,向 table 表传输 21 个年份
xor si,si
push si
pop di
cld
mov cx,21
s1: movsw
movsw
add di,12
loop s1
; 向 table 表传输 21 年中,每一年的总收入
mov di,5
mov cx,21
s2: movsw
movsw
add di,12
loop s2
; 向 table 表传输 21 年中,每一年的雇员人数,并计算出人均收入,存入 table 表中
xor bx,bx
mov di,10
mov cx,21
s3: movsw
mov ax,word ptr es:
mov dx,word ptr es:
div word ptr es:
mov word ptr es:,ax
add di,14
add bx,16
loop s3
mov ax,4c00h
int 21h
code ends
end start
页:
[1]