• 汇编语言实验七


    已知 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 
  • 相关阅读:
    Map集合的四种遍历方式
    测试框架:使用SONAR分析代码质量
    什么是蓝绿发布
    linux命令(mac)
    TestNG.xml大全
    Mac端git新增项目
    JavascriptExecutor的UI自动化实战
    git命令及Maven命令
    UI自动化常用代码
    USACO 1.3 Ski Course Design
  • 原文地址:https://www.cnblogs.com/KKSJS/p/9979531.html
走看看 - 开发者的网上家园