循环程序结构和过程调用程序设计

实验目的

(1)掌握分支结构、简单循环结构程序和过程调用的设计和调试方法;
(2)熟练掌握存储器分段和段超越的概念和实现方法;
(3)掌握单字节和双字节在寄存器和存储器中的存放方式;
(4)掌握负数在内存中的表示方法;
(5)掌握数组的编程处理方法以及“冒泡”法排序的编程方法。

实验内容

  1. 编程设计实验(一)
    (1)源代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    DATA SEGMENT
    X DB 32,-43,76,95,-1
    Y DB -78,127,-128,-125,88
    LEN EQU $-Y
    SUM DB 5 DUP (?)
    DATA ENDS
    CODE SEGMENT
    ASSUME CS:CODE,DS:DATA
    START:
    MOV AX,DATA
    MOV DS,AX
    MOV CX,LEN
    MOV BX,0
    L1:MOV AL,X[BX]
    ADD AL,Y[BX]
    MOV SUM[BX],AL
    INC BX
    LOOP L1
    L2:JMP L2
    CODE ENDS
    END START

    (2)反汇编结果:
    F7-L-2-XR-2-4-MMOJ-U-ER.png
    (3)运行结果
    程序执行完毕结果:
    PKL5-GWI4-B-LL44-J-Q-P7.png
    K90-QI15-N-0-T-UALOWB7-BG.png

  2. 编程设计实验(二)
    (1)源代码:

    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
    DATA SEGMENT
    X DB 32,-43,76,95,-1,-78,127,-128,-125,88
    XLEN EQU $-X
    DATA ENDS
    EXTRA SEGMENT
    Y DB 10 DUP(0)
    EXTRA ENDS
    CODE SEGMENT
    ASSUME DS:DATA,CS:CODE,ES:EXTRA
    START:MOV AX,DATA
    MOV DS,AX
    MOV AX,EXTRA
    MOV ES,AX
    CALL PROC1
    LP4:JMP LP4

    PROC1 PROC NEAR
    MOV SI,0
    MOV CX,XLEN-1
    LEA BX,X
    LP1:MOV SI,0
    PUSH CX
    LP2:MOV AL,DS:[BX+SI]
    CMP AL,DS:[BX+SI+1H]
    JG CHANGE
    JLE ADD1
    CHANGE:XCHG AL,DS:[BX+SI+1H]
    MOV DS:[BX+SI],AL
    ADD1:INC SI
    LOOP LP2
    POP CX
    LOOP LP1
    MOV SI,0
    MOV CX,XLEN
    LP3:MOV AL,X[SI]
    MOV ES:[SI],AL
    INC SI
    LOOP LP3
    RET
    PROC1 ENDP
    CODE ENDS
    END START

    (2)反汇编结果:
    HPH6-CCNU3-QBA3-WVW-PXOA.png
    (3)运行结果
    8-CM-792-O5-FPE2-HV5-N6-V.png
    排序前DS:
    F-ORF5-NJD-496-CT7-ZJV-R.png
    排序前ES:
    W-YNS-G-U8-D9-M-7-06-OW.png
    排序后DS:
    L6-0-Z-943-IM3-AFXCZ2-8-B.png
    排序后ES:
    0-W1-NPUWYU-48-7-UWK-XJ.png
    三、实验中遇到的问题及分析
    1、实验中遇到的问题
    2、分析总结”实验报告要求”中的提问问题。
    (1)要求根据实验内容画出正确的程序流程图、编写完整的源程序代码
    代码如上文
    流程图:
    0-R6-KD-Y9-X-GQX1-L-CX41.png
    A40-PHA-M-C-XUT-O42-W74.png
    (2)总结编程设计实验(二)②中设置断点的位置和调试方法
    内循环LOOP LP2处设置断点
    在外循环LP1处设置断点
    在CALL PROC1 下一行(LP4:JMP LP4)设置断点
    在使用单步执行后观察每一步的内存变化。
    (3)总结双重循环程序和子程序的结构特点和调试方法
    双重循环:
    由两个LOOP嵌套而来,也可以使用两个条件转移指令(JC,JZ,JA,JG等)嵌套得来,也可混合使用。
    如果使用LOOP嵌套,由于结束循环条件都是CX是否为零,因此需要在外循环开始是先对CX入栈,为内循环创造正确的结束判断条件,在内循环结束时对CX出栈,为外循环保留正确的结束判断条件,这种CX保留方式无法完全切割内外循环判断条件的联系,内循环的循环次数仍然会随着外循环的进行而每次减一,正适用于冒泡法排序(外循环每循环一次,内循环就少一次循环次数)。如果内循环次数固定,可以通过对CX入栈后重新对CX进行赋值的方式,确保内循环次数的正确性。
    如果使用条件转移指令嵌套,则可以为内外循环设置不同的循环结束条件,通常使用两个CMP指令来配合两个条件转移指令使用。
    调试方法:先在内重循环处调试,在到外层循环处看执行程序结果是否正确。
    子程序调用:
    子程序结构
    调用指令的执行过程
    1.保护断点
    将调用指令的下一条地址(断点)压入堆栈(CS,IP)
    2.获得子程序的入口地址(label)
    子程序第一条指令地址
    3.执行子程序(程序员完成)
    功能实现,参数的保存和恢复(CS,IP)
    4.恢复断点
    将断点的偏移地址弹出。
    子程序(过程)调用应处理好三个问题
    1.保护断点(CS,IP入栈及出栈)
    2.保护现场:子程序中用到寄存器/存储器需要保护
    3.参数传递
    调试方法:子程序执行完成一次检查一次。
    (4)总结子程序传递参数的方法,以及寄存器、变量和堆栈传递方法的优缺点
    入口参数(也称入口条件):是指主程序调用子程序前,为子程序内部数据处理准备所需的预置值;
    出口参数:(也称出口条件):是子程序返回主程序后,把子程序处理的结果传递给主程序的数据。
    参数传递的基本方法有一下三种:
    ①寄存器传参:通过CPU寄存器传递参数。传递数据方便、快捷,但所能传递的数据长度和个数都有限。
    ②存储单元传参:通过内存单元(组)传递参数。传递数据的长度和个数可不受限制,程序设计比较灵活。
    ③堆栈传参:用堆栈保存所要传递的数据或存储地址,利用堆栈数据存取的特点(后进先出),是常用的参数传递方法。
    本次实验所用代码使用的是存储单元传参