鱼C论坛

 找回密码
 立即注册
查看: 3311|回复: 0

[汇编作业] 《汇编入门》p42集的"里程碑"问题

[复制链接]
发表于 2021-10-7 19:10:04 | 显示全部楼层 |阅读模式

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

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

x
啊哈哈 我是没想到边看边睡的我能做出来
我觉得这个帖子可以给一些遇到困难的朋友一些帮助
先上源代码 原题见【汇编入门】《零基础入门学习汇编语言》的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:[bx]                        ;ax存放低16位数据
                        mov dx, ds:[bx+2]                     ;dx存放高16位数据
                        
                        ;es为目标地址 di用作偏移 
                        mov es:[di], ax                        ;这段为低16位的数据
                        mov es:[2+di], 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:[bx]                        ;ax存放低16位数据
                        mov dx, ds:[bx+2]                ;dx存放高16位数据
                        
                        mov es:[di], ax
                        mov es:[di+2], 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:[bx]
        
                        mov es:[di], 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:[bx]                        ;低16位
                        mov dx, ds:[bx+2]                   ;高16位
                        
                        div word ptr ds:[si]                  ;做除法运算        ax存放商 dx存放余数
                          
                        mov es:[di], ax                       ;将结果移动至目标地址
                        
                        add bx, 4                                ;公司收入的一个数据是四个字节
                        add si, 2                                ;公司人数的一个数据是两个字节
                        
                        add di, 16
                        
                        loop s4
                        ;---------------------------------------------
                        ;结束程序
                        mov ax, 4c00h
                        int 21h
code ends
end start
总结:整个代码下来花了我不到2个小时的时间

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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 05:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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