欢迎访问东莞自考网!本站非政府官方网站,官方信息以广东省教育考试院(http://eea.gd.gov.cn/)为准。 登录 网站导航

东莞自考网

咨询热线:177-2280-6683

自考办电话 | 在线提问 | 公众号

微型计算机原理及应用学习笔记 汇编语言程序设

编辑整理:东莞自考网 发表时间:2018-05-23 12:28:38   【 】    [添加招生老师微信]


立即购买

《自考视频课程》名师讲解,轻松易懂,助您轻松上岸!低至199元/科!

一、概述
    单一的指令其功能比较简单,要解决一个实际问题总是需要一组指令按一定的思路有    机地组合起来才能完成,这样一组完成特定功能的指令有序集合称为程序。
  (一)程序设计的步骤
  从具体问题到编好程序要经过如下基本步骤: 
(1)  分析课题——弄清问题的性质、目的,已知数据,运算精度以及速度等方面的要    求。
(2)确定算法——把实际问题转化为计算机求解的步骤和方法,即算法,而程序是用来描述算法的。
  (3)画流程图——流程图是算法的一种直观而形象的表示方法,是对程序执行过程的    一种形象化的描述,又称为框图。 
  (4)编写程序——熟悉8086/8088的指令系统及程序设计常用技巧按流程图编写程    序。要求做到简单明了、层次清晰、运算迅速、少占内存。要编写高质量的汇编语言程序,必须加深对指令系统功能的理解,注意内存工作单元和工作寄存器的分配。  
  (5)上机调试、修改——可以通过单扳机或系统机进行调试、修改直至通过。
    (二)程序的基本结构  
    程序的基本结构有四种:顺序结构,分支程序结构,循环程序结构,子程序结构。现     分节筒述于下。
    二、顺序结构程序
    顺序结构的程序又称简单程序,这种结构的程序是顺序执行的, 无分支,无转移,无循环,程序本身的逻辑很简单,它只依赖于计算机能够顺序执行指令(语句)的特点,只要语句安排的顺序正确即可。
    例1  内存中自TABLESQ开始的16个单元连续存放着自然数0到15的平方值,任
  给一数X(0≤X≤15)在XX单元中,查表求出X的平方值,将结果存入YY单元中。
    首先在数据段中建立平方表,表的首地址为TABLESO,然后用程序找到X2值在平方表中的位置,即计算表地址,表地址 = 表起始地址(TABLESQ)+X,据此可写出如下程序。
    DATA    SEGMENT
     TABLESQ  DB O,1,4,9,16,25,36,49,
             DB 64,81,100,121,144,169,225
     XX   DB  ?
     YY   DB  ?
    DATA    ENDS
    STACK    SEGMENT PARA STACK‘STACK’
     DB  50 DUP(?)
    STACK    ENDS
    CODE    SEGMENT
    ASSUME  CS:CODE,DS:DATA,SS:STACK
    START    PROC FAR   *   *
    BEGIN:  PUSH DS    *   *
    MOV,AX,0          *   *
    PUSH AX             *   *
    MOV  AX,DATA
    MOV  DS,AX
    MOV  BX,OFFSET TABLESQ
    MOV  AH,0
    MOV  AL,XX
    ADD  BX,AX
    MOV  AL,[BX]
    MOV  YY,AL
    RET               *   *
    START  ENDP       *   *
    CODE   ENDS
END BEGIN
其中带 *   * 的六行语句的作用是为了在用户程序运行结束后,正确返回操作系统。    汇编语言源程序经过汇编、连接后生成 .EXE文件,可在DOS下直接键入文件名运行,例如命令 A>EXAMPLE 将把带有.EXE的文件EXAMPLE装入内存,并从程序中指定地址开始运行。装入文件并设置启动地址是由操作系统的COMMAND.COM文件完成的。COMMAND.COM文件在装入.EXE文件前,首先确定最低可用地址作为被装入程序的可用内存起点(该区段称为程序段)并在程序内从段内偏移地址处开辟100H字节的程序段前缀(PSP),在该PSP的前两字节存放一条 INT 20H 指令(即退出当前程序返回操作系统)。而COMMAND.COM把.EXE文件装入后,自动设置DS和ES寄存器指向程序段前缀,即此时的DS和ES值为程序段前缀之段基值。用户程序结束为RET,为使RET后程序转向程序段前缀中INT 20H指令,必须使CS为程序段前缀的段基值,IP为INT 20H的段内偏移值00H,因此必须把用户程序设计为过程,即加下START PROC FAR,在用户程序的前三条指令写入PUSH DS,MOV AX,0和PUSH AX,把DS = 程序段前缀之段基值,AX = 00H进栈,在用户程序最后用RET指令出栈到CS和IP,以保证程序转向INT 20H,进而返回操作系统。
    代码段结束的处理还可用DOS系统功能调用,在结尾处安排如下两条指令
    MOV AH、4CH
    INT 21H
    执行至此,返回调用程序,常用于应用DEBUG进行程序调试,可返回DEBUG。这 时,可不用把用户程序设计为过程,即去除带 *   * 的六行语句。
    例2  把非压缩十进制数转换为压缩十进制数,被转换数存放在DATl开始的两个单    元,转换后的数存回DATl单元。
    程序如下:
    MOV AX,DATI   ;(AX)=0109H
    MOV CL,4      ;(CL)=4
    SAL AH,CL     ;(AH)=10H
    ROL AX,CL     ;(AX)=0091H
    ROL AL,CL     ;(AL)=19H
MOV BYTE PTR DATl,AL    ;(DATl)=19H
    ┅
    DATl DW 0109H
    三、分支结构程序
    在实际的程序设计中,始终是顺序执行的情况是很少的,大部分程序在执行过程中,总是要求计算机作出一些判断,井根据判断作出不同的处理,这就引出了分支程序的概念。
    (一)分支程序的二要素
    分支结构程序是具有判断和转移功能的程序。
    1.判断——根据运算结果的状态标志
    判断前一定要经过运算(能影响状态标志的运算),状态标志反映了运算结果的特性。     这些状态标志是:进位标志CF、奇偶标志PF、零标志ZF、符号标志SF以及溢出标志OF。
    2.转移 — 主要由条件转移指令来实现(也可用无条件转移指令JMP)
    在8086/8088的指令系统中,条件转移指令可分为两大类,一类是按单标志位来判断  的,如JAE,JC,JZ,JO,JS等;另一类是按多标志位来判断,如JGE,JG,JA等,详见表3-6所示。
    分支结构程序框图如图4—1所示。
    (二)利用比较转移指令实现分支
    这是实现分支的一种常用方法,用于比较、判断的指令是CMP(比较指令)、CMPS(串比较指令)以及SCAS(串搜索指令)等。转移指令已如前述。而分支的次数可由具体问题决定是单重分支还是多重分支。n次判断可形成n+l路分支。
    例3  符号函数的处理
    有一符号函数
              1,  当 X>O  (-128≤X≤127)
       Y =     O,  当 X=0
             -1, 当 X<O
    设给定值x存放于LY单元,函数Y值存放于YY单元,则按X的不同取值给Y赋值的程序如下:
      MOV AL.XX
      CMP AL,0
      JGE BIGR
      MOV AL,0FFH
      MOV YY,AL    ;X<0时,—1送入YY单元
      HLT
   BIGR:JE EQUL
      MOV AL,1
一    MOV YY,AL    ;X>O时,l送人YY单元
        HLT
     EQUL:MOV  YY,AL    ;X=O时,O送人YY单元
        HLT
    这是一个多重分支的符号函数赋值程序,其流程图见图4-2 所示。
    例4数据块传送程序
    要求把内存中某一区域的源数据块传送到另一区域。在编写该程序时,必须判别一下    源数据区同目的数据区之间有无重叠,以决定是增量传送还是减量传送。程序清单如下:
    DATA    SEGMENT
    STRG    DB l000 DUP(?)
    STGl    EQU STRG+7
    STG2    EQU STRG+25
    SIRSE   EQU 50
    DATA    ENDS
    STACK   SEGMENT PARA STACK‘STACK’
    STARN    DB l000 DUP(?)
    STACK    ENDS
    COSEG    SEGMENT
    ASSUME CS:COSEG,DS:DATA,ES:DATA,SS:STACK
    GOO  PROC  FAR
    BEGIN: PUSH DS
            MOV  AX,0
            PUSH AX
            MOV  AX,DATA
            MOV  DS,AX
            MOV  ES,AX
            MOV  CX,STRSE
    MOV  SI,OFFSET STGl
            MOV  DI,OFFSET STG2 
            CLD                   ;增量方式
PUSHI SI
ADD  SI,STRSE-1
            CMP  SI,DI
            POP  SI
            JB  OK
            STD                  ;减量方式传送
            ADD  DI,STRSE-1     ;指向数据块底部
            ADD  SI,STRSE-1
        OK:REP MOVSB            ;重复传送50个数据
              RET
GOO    ENDP
        COSEG    ENDS
          END BEGIN
    (三)利用跳转表实现分支
    1.跳转表的建立
    在内存的一个连续区中,连续存放一系列跳转地址、跳转指令或关键字,组成一个决
  定程序分支的跳转表。
     例5  某工厂有8种产品的加工程序RO到R7分别存放在以SBRO,SBRl,…,SBR7为首地址的内存区域中,这8个首地址的偏移量连续存放在以BASE为首地址跳转表内,如图4-3 所示。
2.跳转表的使用
上例中,8种产品的编号为0,1,2,…,7 如果已知目前要加工的产品编号,要求编写程序,利用跳转表自动转入该产品的加工程序。
    在跳转表已知的情况下,关键问题要计算所要求的加工程序的入口地址在跳转表中的地址,即计算表地址。从图 4-3可见:
表地址=表基地址+偏移量
表基地址即跳转表的首地址,偏移量即对应的程序入口地址在表中的地址与表基地址
的距离。在本例中,分析表的结构可见,偏移量=产品编号 * 2,已知偏移量后,即可求出表地址。据此可写出[例5]的程序清单
    DATA    SEGMENT
    BASE  DW SBR0,SBRl,SBR2,SBR3
          DW SBR4,SBR5,SBR6,SBR7
    BN    DB ?
    DATA  ENDS
    STACK SEGMENT PARA STACK ‘STACK’
      DB  l00 DUP(?)
    STACK ENDS
    COSEG  SEGMENT
       ASSUME CS:COSEG,DS:DATA,SS:STACK
    START PROC FAR
    BEGIN:PUSH  DS
           MOV  AX,O
           PUSH  AX
           MOV  AX,DATA
           MOV  DS,AX
MOV  AL,BiN
                            MOV  AH.O
           ADD  AL,AL
           MOV  BX,OFFSETBASE
           ADD  BX,AX
           MOV  AX,[Bx]
           JMP  AX
           RET
           START  ENDP
           COSEG  ENDS
           END BEGIN 
    3.根据跳转表内指令分支
    在计算机系统的监控程序,键盘管理程序中经常要用到跳转表。在跳转表中既可存放    跳转地址(如例5),也可存放一系列的跳转指令JMP。
    例6  有一监控程序的键盘程序控制12个命令键——执行键(EXEC)、存储器检查键(MEM)等等,按下任一命令键相当于发出一条键盘命令,而这些命令的实现分别由监控程序中的12个于程序完成,这些子程序的入口地址分别为ADR0,ADRl,…,ADRll。据此可以  组成命令键跳转表如图4-4所示。该命令键跳转表存放在以BASE0为首地址的内存区域中,表内存放着12条转移指令:
    JMP  ADR0,JMP  ADRl,  …,JMP ADRll。
设12个命令键的编号分别为0 ~ 11。命令跳转表中每三个单元存放一条转移指令,如果命令键的编号X已送入寄存器AL,则实现转向相应的命令子程序的程序如下
    MOV  AH,0
    MOV  BL,AL
    ADD  AL,AL
ADD  AL,BL
ADD  AL, BL
    MOV  BX,OFFSET BASE0
    ADD  BX,AX          ;表地址计算
    JMP  BX
  
四、循环结构程序
    (一)概述
    1.循环程序
    实现重复执行某一段程序的程序结构称为循环程序。用来处理带重复性的问题,可以缩短源程序及目标程序。
    循环结构程序的框图之一如图4-5所示。
    循环程序由五部分组成:
    (1)初始化部分——这是循环的准备部分,为程序操作、地址指针、循环计数、结束条件等设置初始值。
   (2)循环工作部分——这是循环程序的主体,完成程序的基本操作,循环多少次,这部分的语句就执行多少次。
    (3)循环修改部分——修改循环工作部分的变量地址等,为下一轮重复操作作准备。
    (4)循环控制部分——修改计数器或判断循环结束条件以决定是继续循环还是终止循环,是典型的分支结构,不过继续
  循环的分支去向是循环体的头部。通常把循环工作部分称为循环体,循环体的第一条指令为循环体的头部。
    (5)循环结束部分——循环终止后,对循环结果的处理部分。
    2.循环程序的几种结构形式
    循环程序除图4-5所示的基本结构形式外,还有两种常用的结构形式,如图4-6和图
4-7所示。
    这两种结构的特点是工作部分放在循环控制部分之后,这样可以允许循环次数为零的    循环程序或不需要循环时不进入循环工作部分。
    3.循环程序分类
    (1)按循环控制条件分类
    1)计数循环——重复次数已知,用计数值控制循环的开始与终止。
    2)条件控制循环——重复次数未知或不确定,需找出循环控制的条件。
    (2)按循环体内结构分类
    1)单重循环——循环体内只是顺序程序或分支程序,不再有循环程序。
    2)多重循环——循环体内再套有循环程序。可把重复处理部分独立出来,前面加上    循环准备,后面加上结束判断。
    4.循环程序设计要点
    循环程序设计要点可归结为两点:
    (1)怎样把求解的问题变为循环结构的程序类型——怎样实现重复,即计算方案的循    环化。这里循环工作部分的设计尤为重要,因为这是多次重复的部分,注意程序的精练,及循环体头部的确定。
    (2)怎样使循环准确地执行完毕,这就要注意循环控制部分的设计。特别是对条件控    制的循环,注意设置循环结束标志。
    (二)循环程序举例
    例7计算Y=∑ai  , 0≤i≤100
有100个数a1,a2,…,a100,求这100个数之和(设和值不大于2个字节)。采用循环结构可写出如下程序:
DATA  SEGMENT
    TABL  DW a1,a2,…,a10
          DW all,a12,…,a20
           …      
          DW a91,a92,…,a100
    YY    DW ?
    DATA  ENDS
    STACK  SEGMENT PARA  STACK‘STACK’
          DB  l00 DUP(?)
    STACK  ENDS
    CODE  SEGMENT
      ASSUME CS:CODE,DS:DATA,SS:STACK
    GO  PROC FAR
    BEGIN:PUSH DS
           MOV AX,O
           PUSH AX
MOV AX,DATA
MOV DS, AX
MOV AX,0
MOV BX, OFFSET TABL  
MOV CX, 100
LOP:   ADD AX,[Bx]
INC BX
INC BX
DEC CX
JNZ LOP
MOV YY,  AX
RET
GO:    ENDP
CODE   ENDS
例8         统计数组中负元素的个数
数据段的定义如下:
DATA  SEGMENT
D1 DB -1,-3,5,6,-9,…
COUNT EQU $-D1
RS DW ?
DATA  ENDS
代码段程序为:
CODE SEGMENT
ASSUME CS:CODE,SS:STACK, DS:DATA
START PROC FAR
BEGING: PUSH DS
MOV AX,0
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET D1     ;建立数据指针
MOV CX,COUNT         ;置计数器初值
MOV DX,0             ;置结果初值
LOP1: MOV AL,[BX]
CMP AL,0
JGE JUS
INC DX
JUS:  INC BX
DEC CX
JNZ LOP1
MOV RS,DX
RET
START ENDP
CODE ENDS
以上两例都是‘‘先执行,后判断”的结构。
 
    例9  寄存器AX中有一个16位二进制数,编程统计其中“1”的个数,结果存放在
CX中。
本例最好采用“先判断、后执行”的结构,即先检查凡x中有无为“1”的位。则代码段的有关程序如下:
MOV  CX, 0
LOP:  AND  AX, AX
JZ   STP
SAL  AX, 1
JNC  LOP
INC  CX
JMP  LOP
STP: HLT
例10  软件延时程序如下:
SOFTDLY PROC
MOV BL,10
DELAY: MOV CX, 2801
WAIT:  LOOP WAIT
DEC BL
JNZ DELAY
RET
 SOFTDLY ENDP
    这是一个二重循环结构,内循环即WAIT:LOOPWAIT,每个内循环可实现延时10ms左右,外循环人口为DELAY:MOV CX,2801,共进行10次,总的延时时间约lOOms。
    注意:可以从内循环直接跳到外循环,但不能从外循环直接跳进内循环。特别要注意  100循环体头部,防止死循环。
    五、子程序
    (一)概述
    1.子程序结构
    如果在一个程序中的多个地方或在多个程序中都要用到同一段程序,可以把该程序段    独立出来存放在内存的某一区域以供其他程序调用,这段程序称为子程序或过程。可见子    程序是可供其他程序调用的独立的、相对固定的程序段。调用子程序的程序体称为主程序    或调用程序。在实用中总把常用的子程序标准化后存放在一个内存区中,称为“子程序    库”。
    (1)结构。子程序的第一个语句前必须有“过程名”——入口地址的符号表示,出口是返回指令RET。
    (2)调用与返回。主程序通过书写调用指令CALL后跟子程序的入口地址来调用子    程序,8086/8088允许子程序在现行代码段中(子程序名为NEAR类型),也可以不在现行代码段中(子程序名为FAR类型)。为了保证正确返回,RET指令的类型,必须与CALL指令的类型相匹配。
    1)调用指令中的目标地址有两种表示方法:
    a.直接调用,目标地址就在指令中。例如:CALL NEAR-PRG  。
b.间接调用,目标地址在由指令指定的寄存器或内存单元中。例如:CALL DWORD PTR[BX]    对段内的直接调用而言,CALL指令首先将SP减2,使断点的IP栈,从指令中得到的目标过程的相对偏移量(最大不能越界)加到IP上。对段内的间接调用而言,以CALL AX为例,SP减2,IP进栈,AX→IP。
对段间的直接调用而言,SP减2,现行代码段寄存器CS的内容进栈,CS由指令中目标过程的段基值代入。SP再减2,IP进栈,然后将指令中的偏移地址代入IP。
    对段间的间接调用而言,SP减2,把现行的CS值进栈,CS由指令指定的双字存储器指针的第二个字的内容代入,SP再减2,IP进栈,然后IP由指令中指定的双字指针的第一个字的内容代入。双字存储器由数据段定义。
    2)返回指令RET也有两种情况:
    a. 段内返回指令,把SP所指的堆栈顶部的一个字的内容弹回IP,SP加2。
    b.段间返回指令,把SP所指的堆栈顶部的两个字的内容,先弹回IP,后弹回CS,SP加4。
    2.子程序文件
    子程序应以文件形式编写,子程序文件由子程序说明和子程序构成。
   (1)子程序说明。子程序说明包括如下部分:
    1)功能描述:包括子程序名称、功能,以及性能指标(如执行时间)等o
    2)所用寄存器和存储单元。
    3)子程序的入口、出口参数。
    4)子程序中又调用的其他子程序。
    5)调用实例(可无)。
 子程序说明举例如下:
    ;子程序PTOB
    ;两位十进制数(BCD码)转换成二进制数
    ;入口参数:AL中存放被转换数
    ;出口参数:CL中存放转换后的二进制数
    ;所用寄存器:BX
    ;执行时间:0.06ms
  (2)子程序。在8086/8088中,子程序本身常以过程形式存放在代码段中,以一个过    程名开始,以RET指令结束。
    例如: DTOB  PROC
           …
RET
           DTOB  ENDP
    3.子程序应用中应注意的问题
    (1)主程序与子程序的连接。主程序与子程序的连接由下例可见:
    例如;
    CODE  SEGMENT
      START:…  
          MOV AL,XX    ;被转换的数在XX单元
          PUSH BX
    CALL DTOB
    MOV YY,CL    ;转换结果存于YY单元
    POP BX
     …
    DTOB  PROC  
    RET
    DTOB    ENDP
    CODE    ENDS
    END START
    (2)子程序中所用寄存器及工作单元内容的保护。为了不破坏原有信息,对于在子程    序中要用到的某些寄存器和存储单元的内容,必须压入堆栈加以保护,也可存入一些空闲单元或某些目前不用的寄存器中。称为现场信息的保护。保护可以在子程序中实现,可在主程序中实现,一般在子程序中实现保护比较好。而对于用作中断服务的子程序,则一定在子程序中安排保护指令,因为中断的出现是随机的,无法在主程序中安排保护程序。
    (3)参数的传递。主程序与子程序通常需要交换信息,在多数情况下主程序需要向子  程序传递参数,子程序执行的结果要传送给主程序。子程序清单中的人口参数使子程序  对不同的数进行处理,出口参数可送出不同的结果。
     参数传递一般有三种方法:
  1)用寄存器传递,适用于参数较少的情况;
  2)用参数表传递,适用于参数较多的情况,要求事先建立参数表,参数表一般建立在内存中。
  3)用堆栈传递,适用于参数多并子程序有嵌套、递归调用的情况,主程序将参数压入堆栈,子程序中将参数从堆栈弹出。
4.子程序嵌套和子程序递归
    (1) 子程序嵌套 。子程序调用别的子程序,称为嵌套,。嵌套的层次只受空间的大小
的限制。
    (2)子程序递归。子程序直接或间接地调用子程序自身,称为递归。
    (二)子程序结构举例
    例11  数据段定义了两个数组ARYl和,ARY2,编一程序分别求此两数之和。主程序和过程分别安排在两个不同的段中,因此过程应是FAR类型。
    该程序清单如下
    STACK  SEGMENT PARA STACK
     DW 20 DUP(?)
STACK  ENDS
DATA  SEGMENT
ARY1 DB 100 DUP(?)
SUM1 DW ?
ARY2 DB 50 DUP(?)
SUM2 DW ?
DATA  ENDS
MAIN  SEGMENT          ;主程序段       
   ASSUME CS:MAIN, DS:DATA,SS:STACK
STR:PUSH DS
MOV AX,0
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AX,SIZE ARY1
PUSH AX           ;SUM过程的入口参数1 进栈
MOV AX,OFFSET ARY1
PUSH AX          
CALL SUM
   …
MOV AX,SIZE ARY2
PUSH AX           ;SUM过程的入口参数2 进栈
MOV AX,OFFSET ARY2
PUSH AX          
CALL SUM
HIT
MAIN  ENDS
 
 
 PROCE  SEGMENT     ; 过程段
        ASSUME  CS:PROCE,DS:DATA,SS:STACK
SUM  PROC FAR
PUSH AX
PUSH BX
PUSH CX
PUSH BP
N40V BP,SP
PUSHF
MOV CX,[BP+14]
MOV BX,[BP+12]
MOV AX,0
AND:  ADD AL,[BX]
INC BX
ADC AH,0
LOOP ADN
MOV[BX],AX     ;数组之和送到结果区
POPF            ;恢复现场
POP BP
POP CX
POP BX
POP AX
RET 4            ;返回并废除参数1和2
SUM  ENDP
PROCE  ENDS
END STR
 
从程序清单可见主程序向过程的参数传递是通过堆栈实现的,程序执行过程中堆栈变化如图所示。
    图4-8  例u中堆栈变化情况
 
程序中出现RET 4,该指令的功能是返回后,SP再加 4
例12  求n!
算法是
n! =  n(n-1)!   当n>0时;
  1         当n=0时
设数n存放在AL中,n! 存放在BX中。
;主程序
MAIN: MOV AX,3    ;设n=3
       CALL FACT
  X1: MOV BX,DX
       HLT
;阶乘子程序
;人口参数:AL中存放n
;出口参数:DX中存放n!
;所用寄存器:CX
FACT  PROC
CMP AL,0
JNZ IIA
MOV DL,1
RET               ;①
IIA: PUSH AX
DEC  AL
CALL FACT
X2:  POP CX
CALL MULT
X3:  MOV DX,AX
RET           ;②
FACT  ENDP
;无符号字节数乘法子程序
;入口参数:CL、DL中各为一乘数
;出口参数:AX中为乘积
MULT  PROC
… 
 RET     ;③
  MULT  ENDP
    该程序既包括子程序嵌套,也包括子程序递归。该子程序名为FACT,嵌套子程序即
FACT调用另一子程序MULT(无符号字节数乘法子程序),递归子程序即FACT调用FACT。注意三个RET指令的作用。

本文标签:东莞自考 工学类 微型计算机原理及应用学习笔记 汇编语言程序设

转载请注明:文章转载自(http://www.dongguanzikao.com

本文地址:http://www.dongguanzikao.com/zl_gxl/8716.html


《东莞自考网》免责声明:

1、由于考试政策等各方面情况的调整与变化,本网提供的考试信息仅供参考,最终考试信息请以省考试院及院校官方发布的信息为准。

2、本站内容部分信息均来源网络收集整理或来源出处标注为其它媒体的稿件转载,免费转载出于非商业性学习目的,版权归原作者所有,如有内容与版权问题等请与本站联系。联系邮箱:812379481@qq.com

东莞自考-便捷服务