• 汇编语言实验7:子程序结构设计


    实验七 子程序结构程序设计

    1. 实验目的

    1. 掌握汇编语言程序设计的基本方法和技能
    2. 掌握汇编语言源程序的编辑汇编连接和执行的完整过程
    3. 掌握汇编过程中各种命令的作用及使用方法
    4. 掌握汇编语言中的子程序结构的程序设计方法和流程

    2. 实验任务

    1. 熟悉汇编语言环境,熟练汇编语言的编写
    2. 学习子程序结构的汇编语言程序的设计和调试
    3. 加深对汇编语言子程序结构的理解
    4. 加深对汇编语言整体的认识和把握
    5. 掌握在汇编语言中子程序结构程序的实现方法和流程

    3. 实验步骤

    3.1 子程序结构题目设计

    1. 利用递归的方法求N的阶乘。
    1. 十进制到十六进制的转换程序:从键盘输入一个十进制数,然后把该数以十六进制的形式显示在屏幕上。
    1. 调用子程序进行数组求和(不考虑溢出情况),其数组元素和结果均为字型数据。

    3.2 编写代码

    代码一

    DATAS SEGMENT
        ;此处输入数据段代码 
        N DW 6
        FN DW ? ;存储阶乘结果FN 
    DATAS ENDS
    STACKS SEGMENT
        ;此处输入堆栈段代码
    STACKS ENDS
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        MOV AX,DATAS
        MOV DS,AX
        ;此处输入代码段代码
        MOV AX,N    ;N值放入AX寄存器
        CALL FACT   ;调用阶乘子程序
        MOV FN,DX   ;将DX值存储到FN
        JMP EXIT    ;执行结束
    FACT PROC NEAR
        PUSH AX     ;保护现场
        CMP AX,0    ;比较当前N于0的大小
        JA L1       ;大于则跳转L1
        MOV DX,1    ;否则直接DX=1
        JMP L2      ;恢复现场,结束
    L1:
        PUSH AX     ;保护AX
        DEC AX      ;AX<--N-1
        CALL FACT   ;调用子程序求N-1的阶乘
        POP AX      ;恢复AX
        MUL DL      ;AX<--DL*AX
        MOV DX,AX   ;DX<--AX 存储当前乘积值
    L2:
        POP AX      ;恢复现场AX
        RET
    FACT ENDP
    DPCRLF PROC     ;光标回车换行子程序
        PUSH AX
        PUSH DX
        MOV AH,2
        MOV DL,0DH
        INT 21H
        MOV AH,2
        MOV DL,0AH
        INT 21H
        POP DX
        POP AX
        RET
    DPCRLF ENDP
    
    EXIT:
        MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    代码二

    DATAS SEGMENT
        ;此处输入数据段代码  
        ARRAY1 DW 2,4,6,8,10,12
        COUNT1 DW ($-ARRAY1)/2    ;数组元素个数
        SUM1 DW ?                ;数组和
        ARRAY2 DW 1,3,5,7,9,11
        COUNT2 DW ($-ARRAY2)/2    ;数组元素个数
        SUM2 DW ?                ;数组和
        TABLE DW 3 DUP(?)        ;地址表
    DATAS ENDS
    STACKS SEGMENT
        ;此处输入堆栈段代码
        DW 32 DUP('S')    ;堆栈段定义
    STACKS ENDS
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        PUSH DS
        XOR AX,AX
        PUSH AX
        MOV AX,DATAS
        MOV DS,AX
        ;此处输入代码段代码
        ;构造地址表
        MOV TABLE,OFFSET ARRAY1
        MOV TABLE+2,OFFSET COUNT1
        MOV TABLE+4,OFFSET SUM1
        ;将地址表的首地址存放到BX
        LEA BX,TABLE
        CALL GET_ARRAY_SUM
        ;构造地址表
        MOV TABLE,OFFSET ARRAY2
        MOV TABLE+2,OFFSET COUNT2
        MOV TABLE+4,OFFSET SUM2
        ;将地址表的首地址存放到BX
        LEA BX,TABLE
        CALL GET_ARRAY_SUM
        JMP EXIT
    GET_ARRAY_SUM PROC
        ;保护现场
        PUSH AX
        PUSH CX
        PUSH SI
        PUSH DI
        MOV SI,[BX]     ;取数组起始地址
        MOV DI,[BX+2]   ;取数组元素个数地址
        MOV CX,[DI]     ;取数组元素个数
        MOV DI,[BX+4]   ;取结果地址
        XOR AX,AX       ;累加器清零
    NEXT:
        ADD AX,[SI]     ;累加和
        ADD SI,TYPE ARRAY1  ;修改地址指针
        LOOP NEXT
        MOV [DI],AX     ;存和
        ;恢复寄存器
        POP DI
        POP SI
        POP CX
        POP AX
        RET
    GET_ARRAY_SUM ENDP
    EXIT:
        MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    代码三

    DATAS SEGMENT
        ;此处输入数据段代码  
    DATAS ENDS
    STACKS SEGMENT
        ;此处输入堆栈段代码
    STACKS ENDS
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        MOV AX,DATAS
        MOV DS,AX
        ;此处输入代码段代码
        CALL DECTOHEX
        JMP E
    DECTOBIN PROC   ;十进制到二进制,转换后的二进制数存在BX中
        MOV BX,0
    NEWCHAR:
        MOV AH,1
        INT 21H
        SUB AL,30H
        JL EXIT
        CMP AL,9
        JG EXIT
        CBW
        XCHG AX,BX
        MOV CX,10
        MUL CX
        XCHG AX,BX
        ADD BX,AX
        JMP NEWCHAR
    EXIT:
        RET
    DECTOBIN ENDP
    BINTOHEX PROC   ;二进制到十六进制并显示输出
        MOV CH,4
    ROTATE:
        MOV CL,4
        ROL BX,CL
        MOV AL,BL
        AND AL,0FH
        ADD AL,30H
        CMP AL,3AH
        JL PRINTIT
        ADD AL,7
    PRINTIT:
        MOV DL,AL
        MOV AH,2
        INT 21H
        DEC CH
        JNZ ROTATE
        RET
    BINTOHEX ENDP
    DECTOHEX PROC   ;十进制到十六进制子程序
        PUSH DS
        SUB AX,AX
        PUSH AX
        CALL DECTOBIN
        CALL BINTOHEX
        CALL NEWLINE
        ;恢复现场 不恢复造成程序死循环
        POP AX          
        POP DS
        RET
    DECTOHEX ENDP
    NEWLINE PROC    ;回车换行
        MOV DL,0DH
        MOV AH,2
        INT 21H
        MOV DL,0AH
        INT 21H
        RET
    NEWLINE ENDP
    E:
        MOV AH,4CH
        INT 21H
    CODES ENDS
        END START
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    3.3 代码分析

    代码一
    主程序:将N值存入AX做入口参数,调用子程序FACT,结果存放在DX寄存器中,最后将DX的结果转移至FN内存单元。子程序:首先保护现场,比较当前N值与0的大小,如果大于,跳转到L1执行,否则DX=1,恢复现场,程序结束。L1:首先PUSH AX进行保护,将AX-1即N-1调用子程序FACT进行递归操作,最终结果存放于DX。DPCRLF子程序为回车换行。

    代码二
    子程序:DECTOBIN十进制转二进制:入口参数:无,出口参数:转换后的二进制数存在BX中;BINTOHEX二进制转十六进制:入口参数:存放二进制数的BX,出口参数:无。NEWLINE子程序:回车换行。

    代码三
    以计算一个数组和为例,首先构造地址表TABLE:分别将数组首地址,数组元素个数和结果存储地址存放在TABLE中,将地址表TABLE的首地址存放在BX寄存器中,调用子程序GET_ARRAY_SUM求和,程序结束。子程序GET_ARRAY_SUM:首先保护现场,取数组首地址,数组元素个数,结果地址分别存放于SI,CX,DI,AX做累加器首先清零,将[SI]内容与AX相加存于AX,修改SI地址,进行循环操作,最后存入[DI],恢复现场。

    3.4 运行测试

    在这里插入图片描述

    图表 1 代码一测试


    在这里插入图片描述

    图表 2 代码二测试


    在这里插入图片描述

    图表 3 代码三测试


    4. 实验总结

    1. 成功运行了汇编语言代码测试,熟悉了汇编语言运行环境
    2. 掌握了汇编语言子程序设计的基本方法和技能
    3. 在汇编语言子程序设计实验的过程中,有很多心得体会,对汇编语言子程序的设计有了新的见解,在实验的过程中,也遇到了很多问题,通过查阅资料,虚心请教,不断弄懂知识,掌握自己对子程序设计的理解。
  • 相关阅读:
    uView 2.0:uni-app生态的利剑出鞘,引领UI框架新纪元
    安卓Frida 脱壳
    假如面试官问你Babel的原理该怎么回答
    如何安装Nacos服务器?
    【TA-霜狼_may-《百人计划》】图形3.2 混合模式及剔除
    脊髓横切面神经示意图,脊髓水平切面结构图
    谈谈 Spring 的过滤器和拦截器
    SQL注入之宽字节注入
    Java学习笔记15——类型转换(基本数据类型)
    TIA博途V17中ProDiag功能的使用方法示例(三)文本列表
  • 原文地址:https://blog.csdn.net/weixin_52117223/article/details/127784451