zoukankan      html  css  js  c++  java
  • 汇编语言实验七

    已知 data 段:

    assume cs:codesg
    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年的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型数据
    
      dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
      dw 11542,14430,15257,17800
      # 以上表示21年公司雇员人数的21个word型数据
    data ends
    
    table segment
      db 21 dup ('year summ ne ??')
    table ends

    编程,将 data 段中的数据按如下格式写入到 table 段中,并计算 21 年中的人均收入(取整),结果也按照下面的格式保存在 table 段中。

    代码和分析如下:

    # 思考两个问题: 1. 要处理的数据在什么地方?(数据源在 data 段中; 数据目的在 table 段中)   2. 要处理的数据有多长?
    # 
    # 将 data 段中的数据看作多个数组; table 段中的数据看作一个数组,数组的每一个元素是一个结构体
    # 
    # 对 data 段中的数据进行**重排**, 成一个结构体的数组, 只需循环 21 次, 每次完成一个数组结构体元素的赋值
    #
    # [bx].idata[di] 用来定位 table 段 ; [bp + si] 用来定位 data 段
    #
    # 1. 初始化操作:
    #    
    #    1)取得data段和table的段的起始地址,分别用 ds:si 和 es:di 指向
    #    2)初始化cx的值为21,也就是循环次数为21
    #    3)引入bx,控制si的增量保持为4。原因:雇员和人均收入记录中的每个数据项长度是2,而其它每个数据项的
    #      长度均为4,为了能在一个循环中进行操作,必须使得他们的增量保持一致
    #    4)入口地址:标号next:
    #  
    # 2. 循环体
    #
    #    1)移动年份数据
    #    2)移动总收入数据
    #    3)sub si,bx
    #    4)移动雇员数据
    #    5)进行除法操作求出人均收入,并移动人均收入
    #  
    # 3. 参数修改
    #
    #    1)si增加4,用si指向每个数据项
    #    2)di增加16,用di指向每行
    #    3)bx增加2,与sub si,bx配合控制雇员和人均收入两个数据在data段中的位置
    # 
    # 4. 循环控制
    #    loop next
    # 
    # 5. 程序返回
    #    mov ah,4ch
    #    int 21h
    assume cs:codesg
    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年的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型数据
    
      dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
      dw 11542,14430,15257,17800
      # 以上表示21年公司雇员人数的21个word型数据data ends
    data ends
    
    table segment
      db 21 dup ('year summ ne ?? ')
    table ends
    
    codesg segment
        start:  mov ax,data
                mov ds,ax
                mov ax,table
                mov es,ax               ;将源数据和目的数据的段地址记录在段寄存器中
    
                sub si,si
                sub di,di               ;分别存放两个数据段的偏移地址, 初始值是 0
    
                mov cx,21
                sub bx,bx               ;这里引入bx是为了很好的控制一次循环过后 si 的增量保持在 4
    
                
                # 下面移动年份数据, 一次循环需要移动 4 个字节
        next:   mov ax , ds:[si]
                mov es:di , ax                    ;先移动头 2 个字节
                
                mov ax , ds:[si+2]
                mov es:[di+2] , ax                ;再移动后 2 个字节
                
                mov byte ptr es:[di+4] , 20h      ;向目的地的年份数据后面放一个空格(大小为一个字节)
    
                
                # 下面移动收入数据, 一次循环需要移动 4 个字节
                mov ax , ds:[si+84]
                mov es:[di+5] , ax                ;先移动头 2 个字节     
                
                mov ax , ds:[si+86]
                mov es:[di+7] , ax                ;再移动后 2 个字节     
                
                mov byte ptr es:[di+9] , 20h      ;向目的地的收入数据后面放一个空格(大小为一个字节)          
    
                
                # 下面移动雇员数据, 一次循环需要移动 2 个字节
                sub si , bx                         ;bx 用来补齐
                mov ax , ds:[si+168]
                mov es:[di+10] , ax                ;先移动头 2 个字节     
                add si , bx                         ;还原 si
                mov byte ptr es:[di+12] , 20h      ;向目的地的雇员数据后面放一个空格(大小为一个字节)
    
    
                # 计算平均收入数据
                mov dx , ds:[si+86]           ; 移动被除数高 16 bit
                mov ax , ds:[si+84]           ; 移动被除数低 16 bit
    
                div word ptr es:[di+10]       ; 进行除法操作求出人均收入
                mov es:[di+13],ax             ; ax默认存储商, bx默认存储余数
                mov byte ptr es:[di+15],20h
              
                add si , 4                                  
                add di , 16                                  ;  si->  0       4       8       12 
                add bx , 2   ;  如果不加 2 的话, 会遗漏数据-->   ;  bx->  0   2   4   6   8   10  12  
                loop next                                    ;        3   7   9   13  28  38  130
    
                mov ah , 4ch
                int 21h
    codesg ends
    end start 
  • 相关阅读:
    Lambda表达式、依赖倒置
    ASP.NET vNext 概述
    Uname
    RHEL4 i386下安装rdesktop【原创】
    Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
    How to decompile class file in Java and Eclipse
    先有的资源,能看的速度看,不能看的,抽时间看。说不定那天就真的打不开了(转)
    Google App Engine 学习和实践
    【VBA研究】VBA通过HTTP协议实现邮件轨迹跟踪查询
    js正則表達式语法
  • 原文地址:https://www.cnblogs.com/KKSJS/p/9979531.html
Copyright © 2011-2022 走看看