鱼C论坛

 找回密码
 立即注册
查看: 613|回复: 2

[争议讨论] 实验七疑问

[复制链接]
发表于 2024-9-25 20:23:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. assume cs: codesg
  2. data segment
  3.         db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  4.         db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  5.         db '1993','1994','1995'
  6. ;以上是表示21年的21个字符串
  7.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  8.         dd 345980,590827 , 803530,1183000,1843000,2759000,3753000,4649000,5937000
  9. ;以上是表示21年公司总收入的21个dword型数据
  10.         dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  11.         dw 11542,14430,15257,17800
  12. ;以上是表示21年公司雇员人数的21个word型数据
  13. data ends
  14. table segment
  15.         db 21 dup ('year summ ne ?? ')
  16. table ends
  17. stacksg segment
  18.         dw 0
  19. stacksg ends
  20. codesg segment
  21. start:
  22.         mov ax,data
  23.         mov es,ax
  24.         mov ax,table
  25.         mov ds,ax
  26.         mov ax,stacksg
  27.         mov ss,ax
  28.         mov sp,2

  29.         mov bx,0
  30.         mov bp,0
  31.         mov di,0
  32.         mov cx,21;21行
  33. s:        push cx
  34.         mov ax,20h
  35.         ;空格
  36.         mov ds:[bp].4h,ax
  37.         mov ds:[bp].9h,ax
  38.         mov ds:[bp].0ch,ax
  39.         mov ds:[bp].0fh,ax

  40.         mov si,0
  41.         mov cx,4;
  42. s1:        mov al,es:[bx][si];获取年份
  43.         mov ds:[bp][si],al;写入年份
  44.         mov al,es:[bx].54h[si];获取公司总收入
  45.         mov ds:[bp].5[si],al;写入公司总收入
  46.         inc si
  47.         loop s1

  48.         mov ax,es:[di].0a8h;获取雇员人数
  49.         mov ds:[bp].0ah,ax;写入雇员人数
  50.         add di,2

  51.         mov ax,ds:[bp].5;获取公司总收入
  52.         mov dx,ds:[bp].7;
  53.         div word ptr ds:[bp].0ah;公司总收入/雇员人数
  54.         mov ds:[bp].0dh,ax;写入人均收入
  55.        
  56.         add bx,4;存放下一个年份和公司总收入的位置
  57.         add bp,16;写入位置的下一行
  58.         pop cx
  59.         loop s
  60.         mov ax,4c00h
  61.         int 21h
  62. codesg ends
  63. end        start
复制代码


此代码功能是实现了,但结束不了,在最后cx等于0的时候不应该再会跳转到s标号处,但用debug调试的时候却会跳转到s标号处,导致会多执行一遍代码,其中进行除法时就是取除数时会取21个雇员人数后的那个数据,为0,除法就会报错,程序就结束不了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-9-25 20:23:57 | 显示全部楼层
你好,鱼油!在你的代码中,CX循环计数器在最后变成0但依旧跳回`s`标号是由于PUSH和POP操作对堆栈的影响。你在`s`标号的开始处使用PUSH CX,将循环计数器CX保存到堆栈中,但你在结束时POP CX时把保存的计数器值恢复,使得CX不为0。从而导致循环继续进行。因此,为了解决这个问题,你需要将PUSH和POP操作与CX赋值区分开来。

修改如下:

  1. assume cs: codesg
  2. data segment
  3.     db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  4.     db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  5.     db '1993','1994','1995'
  6.     dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  7.     dd 345980,590827 , 803530,1183000,1843000,2759000,3753000,4649000,5937000
  8.     dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  9.     dw 11542,14430,15257,17800
  10. data ends

  11. table segment
  12.     db 21 dup ('year summ ne ?? ')
  13. table ends

  14. stacksg segment
  15.     dw 0
  16. stacksg ends

  17. codesg segment
  18. start:
  19.     mov ax, data
  20.     mov es, ax
  21.     mov ax, table
  22.     mov ds, ax
  23.     mov ax, stacksg
  24.     mov ss, ax
  25.     mov sp, 2

  26.     mov bx, 0
  27.     mov bp, 0
  28.     mov di, 0
  29.     mov cx, 21  ; 21行

  30. s:  
  31.     ; 空格初始化
  32.     mov ax, 20h
  33.     mov ds:[bp+4], ax
  34.     mov ds:[bp+9], ax
  35.     mov ds:[bp+12], ax
  36.     mov ds:[bp+15], ax
  37.    
  38.     mov si, 0
  39.     mov cx, 4
  40. s1:
  41.     ; 获取年份
  42.     mov al, es:[bx + si]
  43.     mov ds:[bp + si], al
  44.     ; 获取公司总收入
  45.     mov al, es:[bx + 54h + si]
  46.     mov ds:[bp + 5 + si], al
  47.     inc si
  48.     loop s1
  49.    
  50.     ; 获取雇员人数
  51.     mov ax, es:[bx + 0A8h]
  52.     mov ds:[bp + 0Ah], ax
  53.     add di, 2
  54.    
  55.     ; 公司总收入/雇员人数
  56.     mov ax, ds:[bp + 5]
  57.     mov dx, ds:[bp + 7]
  58.     div word ptr ds:[bp + 0Ah]
  59.     mov ds:[bp + 0Dh], ax

  60.     ; 更新位置
  61.     add bx, 4
  62.     add bp, 16

  63.     dec cx
  64.     jnz s

  65.     mov ax, 4C00h
  66.     int 21h

  67. codesg ends
  68. end start
复制代码


这样的修改确保循环在CX==1时依旧会执行一次,但在这之后不再跳转到s标号,从而避免多执行一次代码。希望这样可以解决你的问题!如果还有其他疑问,请继续提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-9-26 16:41:10 | 显示全部楼层
本帖最后由 jackz007 于 2024-9-26 17:00 编辑

        请试试这个代码
  1. assume cs: code , ds:data , es:table
  2. data segment
  3.         db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  4.         db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  5.         db '1993','1994','1995'
  6. ;以上是表示21年的21个字符串
  7.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  8.         dd 345980,590827 , 803530,1183000,1843000,2759000,3753000,4649000,5937000
  9. ;以上是表示21年公司总收入的21个dword型数据
  10.         dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  11.         dw 11542,14430,15257,17800
  12. ;以上是表示21年公司雇员人数的21个word型数据
  13. data ends
  14. table segment
  15.         db 21 dup ('year summ ne ?? ')
  16. table ends
  17. stack segment stack
  18.         db 400h dup(0)
  19. stack ends
  20. code segment
  21. start:
  22.         mov ax,data
  23.         mov ds,ax
  24.         mov ax,table
  25.         mov es,ax
  26.         mov bx,21*8
  27.         xor si,si
  28.         xor di,di
  29.         mov cx,21
  30.         cld
  31. s:      push cx
  32.         push si
  33.         movsw                       ; 传输年份字符串的头 2 个字符
  34.         movsw                       ; 传输年份字符串的后 2 个字符
  35.         inc di                      ; 跳过表格中的空格
  36.         add si,20*4
  37.         movsw                       ; 传输年度的总收入的低位 Word
  38.         movsw                       ; 传输年度的总收入的高位 Word
  39.         inc di                      ; 跳过表格中的空格
  40.         mov si,bx
  41.         movsw                       ; 传输年度的雇员人数
  42.         inc di                      ; 跳过表格中的空格
  43.         mov ax, es:[di-8]           ; 取得年度总收入的低位 Word
  44.         mov dx, es:[di-6]           ; 取得年度总收入的高位 Word
  45.         div word ptr es:[di-3]      ; 计算年度人均收入      
  46.         stosw                       ; 保存年度人均收入
  47.         inc di                      ; 跳过表格中的空格           
  48.         pop si
  49.         add si,4
  50.         add bx,2
  51.         pop cx
  52.         loop s
  53.         mov ax,4c00h
  54.         int 21h
  55. code ends
  56. end        start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-18 14:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表