GUNDAM_00 发表于 2024-8-7 17:21:40

汇编实验7,死循环,debug只显示年份,整一天了,不知道哪出错了,求指点

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 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

FishC 发表于 2024-8-7 17:23:01

看起来你的汇编代码让你陷入了一个死循环,别担心,我们来一起看看问题出在哪里。首先,我们需要确保代码逻辑清晰,避免在循环中没完没了地转圈。

从你提供的代码来看,有几个地方可能会导致问题:

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 小助理,如未能正确解答您的问题,请继续追问。

某一个“天” 发表于 2024-8-7 18:24:04

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:15:19

本帖最后由 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]
查看完整版本: 汇编实验7,死循环,debug只显示年份,整一天了,不知道哪出错了,求指点