chenpi0527 发表于 2025-3-13 19:44:23

汇编实验七

追了小甲鱼10多年前的视频到现在,留一点学习笔记。
关于汇编实验七--具有里程碑意义的编程,也是花了3天时间从0思考,排查,调试和回看知识点。
【基本思路】
题目给出了4个源数据段,分别是年份、年收入、人数、人均。其中前3个字段是提前定义好的,人均这个字段可以根据年收入除以人数通过循环逐个写入table段;
ds段地址寄存器指向data段,es段地址寄存器指向table目标数据段。
通过4段循环,分别从data数据段按照一定格式导入table数据段。
【问题拆分】
1. 源数据段在哪里?
-A. 年份段:db类型,每1个年份是4个字节(4个单字节字符串),21年就是84个字节。即ds:0~ds:53H;
-B. 年收入段:dd类型,每1个双字类型占用4个字节,21个就是84个字节,继续在54H地址上加。即ds:54H~ds:0A7H;
-C. 人数段:dw类型,每1个字型数据占用2个字节,21个就是42个字节。即ds:0A8H~ds:0D2H;
2. 目标数据段怎么存放?
题目给出了定义21段'year summ ne sr ',这里数了一下,正好是16个字节;
以第一行数据为例:
        年份存在es:~es:;
        年收入存在es:~es:,其中05H、06H存低位数据,07H、08H存高位数据,分别用ax,dx存储低位、高位数据;
        人数存在es:~es:,这里由于是1个字型数据,直接用ax mov过去就行;
        人均存在es:~es:
3. 循环变量:
利用3个计数偏移寄存器bx、di、si来实现:
        年份段:2重循环,内循环bx变量每次+1,外循环si变量+4取到每个年份的第一个字段,di变量+16定位es段的第一位
        年收入段:1层循环,每次si+4指向下一个double word数据,di变量+16定位es段,加上和低位、高位数据段地址
        人数:1层循环,每次si+2指向下一个字型数据,di变量+16定位es段,加上偏移量
        人均:1层循环,仅用di变量+16定位,每一次将es:和es:地址值分别给ax, dx,做除法后商被写入ax,最后mov es:, ax
【源码】
assume cs:code,ds:data,es:table,ss:stack
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 11542,14430,15257,17800
data ends

table segment
        db 21 dup ('year summ ne sr ')
table ends

stack segment
        db 0,0
stack ends

code segment
start:mov ax,data
      mov ds,ax
      mov ax,table
      mov es,ax
      mov si,0       ; 年份数据偏移
      mov di,0       ; table段偏移
      mov cx,20      ; 处理21个年份,这里我用了栈段,第一次push cx没走到loop,cx不会-1,因此初始值设定20

; 复制年份到table段
year_loop:
      push cx
      mov cx,4
      mov bx,0       ; 每次内循环重置bx,这也是我之前排查好久的点,debug一看数据怎么老错位
copy_year:
      mov al,
      mov es:,al
      inc bx
      loop copy_year
      add si,4       ; 下一个年份
      add di,16       ; table下一行
      pop cx
      loop year_loop

; 处理summ(总收入)
      mov si,84      ; summ数据起始偏移(21*4=84)
      mov di,0
      mov cx,21
summ_loop:
      mov ax,   ; 低16位
      mov dx,   ; 高16位
      mov es:,ax
      mov es:,dx
      add si,4      ; 下一个dd
      add di,16
      loop summ_loop

; 处理ne(雇员数)
      mov si,168   ; ne数据起始偏移(84+84=168)
      mov di,0
      mov cx,21
ne_loop:
      mov ax,
      mov es:,ax ; ne字段偏移0AH
      add si,2
      add di,16
      loop ne_loop

; 计算sr(人均收入)
      mov di,0
      mov cx,21
sr_loop:
      mov ax,es:; 总和的低16位
      mov dx,es:; 总和的高16位
      div word ptr es: ; 正确除数:ne字段值
      mov es:,ax ; sr字段偏移0DH
      add di,16
      loop sr_loop

      mov ax,4C00H
      int 21H
code ends
end start

FishC 发表于 2025-3-13 19:46:40

:汇编实验七.asm
startLine: 36
endLine: 108

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 汇编实验七