临时用户3.14159 发表于 2021-10-7 19:10:04

《汇编入门》p42集的"里程碑"问题

啊哈哈 我是没想到边看边睡的我能做出来
我觉得这个帖子可以给一些遇到困难的朋友一些帮助
先上源代码 原题见【汇编入门】《零基础入门学习汇编语言》的p42"寻址方式在结构化数据访问中的应用"
assume cs:code

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'
      ;以上表示21个字节型数据(0 - 53H)
      
      dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514
      dd 345980, 590827, 803530, 1183000, 1843000, 2579000, 3753000, 4649000, 5937000
      ;以上表示21个双字型数据(54H - 0A7H)
      
      dw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 4037, 5635, 8226
      dw 11542, 11430, 15257, 17800
      ;以上表示21个字型数据(0A8H - 0D1H)
data ends

table segment
      db 21 dup ('year summ ne ?? ')
      ;         0123456789ABCDEF
table ends

code segment
      start:      mov ax, data
                        mov ds, ax
                        mov ax, table
                        mov es, ax
                        ;将源地址和目标地址分别与ds es挂钩
                        
                        ;初始化寄存器 cx存放21 后用作循环
                        mov bx, 0
                        mov si, 0
                        mov di, 0
                        mov cx, 21
                        
                        ;----------------------------------------------
                        ;;先存放年份至目标地址(table)
                        ;年份的一个数据是4个字节(4 * 8 = 32位) ax可存放2个字节(2 * 8 = 16位)
                        ;因此 ax用于存放低16位的数据dx用于存放高16位的数据
      s1:            mov ax, ds:                        ;ax存放低16位数据
                        mov dx, ds:                     ;dx存放高16位数据
                        
                        ;es为目标地址 di用作偏移
                        mov es:, ax                        ;这段为低16位的数据
                        mov es:, dx                ;这段为高16为的数据
                        
                        add bx, 4                              ;bx自增2个字(4个字节 32位)
                        add di, 16                              ;di偏移到下一段中
                        loop s1
                        ;---------------------------------------------
                        
                        ;初始化寄存器
                        mov bx, 54H                              ;公司收入的数据存放起点位于54H
                        mov di, 5                              ;table中收入存放位置位于第五位 所以di应该先加上5
                        mov si, 0
                        mov cx, 21                              ;cx继续做21次循环
                        ;---------------------------------------------
                        
                        ;;再将公司收入存放至目标地址(table)
                        ;公司收入的一个数据为dw(4个字节 32位) ax可存放2个字节(16位)
                        ;因此 同样采用上面的方式来移动数据至目标地址(table)
                        
      s2:            mov ax, ds:                        ;ax存放低16位数据
                        mov dx, ds:                ;dx存放高16位数据
                        
                        mov es:, ax
                        mov es:, dx
                        
                        add bx, 4
                        add di, 16
                        loop s2
                        ;---------------------------------------------
                        ;初始化寄存器
                        mov bx, 0A8H                         ;员工人数存放地址起点为0A8H
                        mov di, 0AH                              ;table中公司员工人数的数据存放地址位于一个段中的第10(A)位
                        mov si, 0
                        mov cx, 21
                        
                        ;---------------------------------------------
                        ;将员工人数存放至目标地址(table)
                        ;分析:员工人数的一个数据为字型数据(两个字节 16位) 因此只用一个ax寄存器就可以了
      s3:            mov ax, ds:
      
                        mov es:, ax
                        
                        add ax, 2
                        add di, 16
                        loop s3
                        
                        ;---------------------------------------------
                        ;初始化寄存器
                        mov bx, 54H                                                ;被除数(公司收入)
                        mov si, 0A8H                                        ;除数(员工人数)
                        mov di, 0DH                                                ;目标地址
                        mov cx, 21
                        ;--------------------------------------------
                        ;将公司收入与员工人数做除法运算
                        ;分析:员工人数的一个数据为一个字型数据(两个字节 16位) 因此被除数需要分别存放再ax(低16位) 和 dx(高16位) 中
                        
      s4:            mov ax, ds:                        ;低16位
                        mov dx, ds:                   ;高16位
                        
                        div word ptr ds:                  ;做除法运算      ax存放商 dx存放余数
                        
                        mov es:, ax                     ;将结果移动至目标地址
                        
                        add bx, 4                              ;公司收入的一个数据是四个字节
                        add si, 2                              ;公司人数的一个数据是两个字节
                        
                        add di, 16
                        
                        loop s4
                        ;---------------------------------------------
                        ;结束程序
                        mov ax, 4c00h
                        int 21h
code ends
end start总结:整个代码下来花了我不到2个小时的时间

其实没必要使用那么复杂的寻址方式 这样子完全就可以解决问题 各位可以自己复制去debug中试一下
当然不止这一种方式 这种方式只是我再敲代码时想出来的最优解 这个代码应该可以继续优化下去

页: [1]
查看完整版本: 《汇编入门》p42集的"里程碑"问题