汇编实验代码

一、课程设计的目的与任务

    课程设计是计算机原理与汇编语言教学过程中的重要环节。本课程设计主要目的是使计算机专业学生深入学习计算机原理与汇编语言知识,进一步提高学生计算机原理与汇编语言综合能力和程序设计技能,锻炼运用计算机原理与汇编语言解决实际问题的能力。

二、课程设计的内容

题目一:

1.从键盘输入年份,通过计算后,输出该年份是否为闰年的信息。

判断闰年的规则是:如果某一年能被4整除但不能被100整除或者该年能被400整除,则该年为闰年。

2.输入20~30之间的任一数值,递归计算Fibonacci 数, 以十进制数输出。

3.编写一拷贝程序,要求在命令行指定源文件名和目标文件名。

 

问题解答部分:

 

问题1:从键盘输入年份,通过计算后,输出该年份是否为闰年的信息。

判断闰年的规则是:如果某一年能被4整除但不能被100整除或者该年能被400整除,则该年为闰年。

分析思路流程:


 

   

 

 


               是                             不是

 

 

 

 

 

 

 

 

代码分析:

首先,定义了数据段:

DATAsegment        infon db 0dh,0ah,'Pleaseinput a year: $'   

    Y db 0dh,0ah,'This is a leap year! $' 

    N db 0dh,0ah,'This is not a leap year! $'

    Errordb 0dh,0ah,'the input is wrong!please input after check!$'  

    w dw 0                  ;保存年份

    buf db 6 

        db ? 

        db 6 dup(?)             

DATAends 

在数据段中定义了需要的相关信息,提示字符串以及所需变量。还有一个长度为6的缓冲区来保存输入的年份。

下面定义了转化为数字的程序段:

changeproc               ;将缓冲区的字符转化为数字

          push cx                                                                    

          dec cx              

          lea si,buf+2              

     tt1: inc si                

          loop tt1  ;si指向最大数字

          pop cx                       

          mov dh,30h                

          mov bl,10           

          mov ax,1             

      l1: push ax                

          push bx                

          push dx           

          sub byte ptr  [si],dh         

          mov bl, byte ptr [si]       

          mov bh,0         

          mul bx

          cmp ax,0

          ja wrong

          cmp ax,9

          jb wrong       

          add w,ax                

          pop dx                

          pop bx                ;先保存到栈里,再恢复原来的值,此后bl的值恢复到10 

          pop ax            

          mul bl            

          dec si               

          loop l1

      wrong:

        lea dx,Error

        mov ah,09

        int 21h

        ret                

 change endp 

 change程序段将缓冲区的字符转化为数字形式进行保存,以便下一步可以进行判断。然后将得到的数字进行除法判断。然后根据结果输出是或者不是的字符串。

运行结果如下:

 

我输入了2000和2014进行判断,分别输出了是闰年和不是闰年的信息。由结果可知正确。

完整代码段如下:

DATA segment   ;定义数据段 

    infon db0dh,0ah,'Please input a year: $'   

    Y db0dh,0ah,'This is a leap year! $' 

    N db0dh,0ah,'This is not a leap year! $'

    Error db0dh,0ah,'the input is wrong!please input after check!$'  

    w dw0                  ;保存年份

    buf db6 

        db? 

        db 6dup(?)              

DATA ends 

 

STACK segment stack 

     ;此处输入堆栈段代码

STACK ends                   

 

CODE segment 

         assume ds:DATA,ss:STACK,cs:CODE 

    start:movax,data 

          movds,ax                     

          leadx,infon              

          movah,9 

          int21h               

          leadx,buf              

          movah,10 

          int21h             

          movcl, [buf+1]         

          movch,0               

          leadi,buf+2            

          call change             

         call ifyears               

          jca1               

           

          leadx,n              ;否则输出不是闰年信息 

          movah,9 

          int21h 

          jmpexit 

    a1:   lea dx,y              ;输出是闰年信息 

          movah,9 

          int21h 

    exit: movah,4ch                ;程序结束 

          int21h 

        

  

 

 changeproc               ;将缓冲区的字符转化为数字

         push cx                                                                    

          deccx              

          leasi,buf+2              

     tt1: incsi                

         loop tt1  ;si指向最大数字

          pop cx                       

          movdh,30h                

          movbl,10           

          movax,1             

      l1:push ax                

         push bx                

         push dx           

         sub  byte ptr  [si],dh         

         mov  bl, byte ptr [si]       

         mov  bh,0         

         mul  bx    

          addw,ax                

          popdx               

          popbx                ;先保存到栈里,再恢复原来的值,此后bl的值恢复到10 

          popax            

          mulbl            

          decsi               

         loop l1

       ret                

 changeendp 

 

 

 ifyearsproc                 ;判断是否是闰年的代码段,改变Cf标记位表示不同结果 

          push  bx             

          push  cx              

          push  dx             

          mov ax, w             

          mov  cx,ax             

          mov  dx,0              

          mov bx,100              

          div  bx 

          cmp  dx,0 

          jnz  lab1                

          mov   ax,cx              

          mov bx,400 

          div  bx 

          cmp dx,0 

           jzlab2              

          clc                  ;否则不是闰年,将C标记位清零,并跳转到lab3 

          jmp lab3 

     lab1:mov ax,cx               

          movdx,0              

          movbx,4 

          divbx 

          cmpdx,0 

          jzlab2            

         clc                 

          jmplab3 

     lab2:stc                  ;若是闰年跳转到此处将c标志位置1 ,表示为闰年

     lab3:pop  dx              ;相应寄存器恢复 

          pop  cx 

          pop  bx 

          ret                 

   ifyearsendp 

CODE ends 

   endstart 

 

 

问题二:2.输入20~30之间的任一数值,递归计算Fibonacci 数, 以十进制数输出。

Fibonaccci数列递推式如下所示:

鉴于此,我决定用递归方法来实现数列的求解。在汇编中就是可以调用程序段本身直到当前n等于1或者2,然后每层带着值返回,直到结束。

首先定义一个缓冲区,然后在缓冲区中保存输入的数字,然后将其转化为10进制,将转化后的结果与20和30比较,看是否符合要求。然后把该数字作为循环次数进行递归调用。

INPUT PROC ;判断是否正确输入20-30  

    JMP T1

WRONG:

    LEA DX,WRONGSTR

    mov AH,9

    INT 21H

    JMP START

T1:LEA DX,STR1

    MOV AH,9

    INT 21H

    LEADX,INPUTBUFFER

    MOV AH,10

    INT 21H

    MOV AX,0

    MOVCL,INPUTBUFFER+1 ;?

    MOV CH,0

    LEABX,INPUTBUFFER+2 ;?

    T2:MULC10

    MOVDL,[BX]

    CMPDL,'0'

    JB WRONG

    CMPDL,'9'

    JA WRONG

    ANDDL,0FH

    ADD AL,DL

    ADC AH,0

    INC BX

    LOOP T2

    CMPAX,001EH;判断是否比30大

    JA WRONG

    CMPAX,0014H;判断是否比20小

    JB WRONG

    CMP AX,1

    JB WRONG

    MOV N,AX

    RET

INPUT ENDP

递归调用的程序段:

FIB PROC       

    CMPN,1      

    JZL1      

    CMPN,2      

    JZ L2

    DEC N

    CALLFIB      

    MOVAX,RESULT2L      

    MOVDX,RESULT2H      

    MOVCX,RESULT1L      

    ADDRESULT2L,CX      

    MOV CX,RESULT1H      

    ADCRESULT2H,CX      

    MOVRESULT1L,AX      

    MOVRESULT1H,DX      

    JMPEXIT   

    L1:MOVRESULT1L,1       

    MOVRESULT2L,1     

    JMPEXIT   

    L2:MOVRESULT2L,1       

    DECN       

    CALLFIB     

    EXIT:RET 

FIB ENDP

然后将所得结果转化输出。

运行结果截图如下:

分析上述结果,可以得出程序正确的作出输入判断和输出运行结果的结论。经验证,该结果正确。

 

完整代码:DATAS SEGMENT

    STRING DB 0dh,0ah,'Information Safety 1401hanjun','$'

    STR1 DB 'Please enter a number between 20and 30:N=','$'

    STR2 DB 0dh,0ah,'FIB(N)=','$'

    WRONGSTR DB 0dh,0ah,0dh,0ah,'the numbermust  between 20 and 30  please!',0dh,0ah,0dh,0ah,'$'

    INPUTBUFFER DB 3,?,3 DUP('?')

    N DW ? ;输入N值

    RESULT1H DW 0     

    RESULT1L DW 0

    RESULT2H DW 0  ;结果的高16位       

    RESULT2L DW 0  ;结果的低16位

    C10 DW 10

    OUTPUTBUFFER DB 11 DUP('0')

DATAS ENDS

 

 

STACKS SEGMENT

    ;此处输入堆栈段代码

STACKS ENDS

 

CODES SEGMENT

    ASSUME CS:CODES,DS:DATAS,SS:STACKS

   

START:

    MOV AX,DATAS

    MOV DS,AX

    MOV AH,0

    INT 10H

    MOV BP,SEG STRING

    MOV ES,BP

    MOV BP,OFFSET STRING

    mov cx,32

    MOV DX,0

    MOV BL,41H

    MOV AL,0

    MOV AH,13H

    INT 10H ;彩色字符输出

    lea dx,STRING

    MOV AH,09H

    INT 21H

    MOV DL,0AH

    MOV AH,02H

    INT 21H

    XOR AX,AX

    XOR BX,BX   

    CALL INPUT    

    CALL FIB    

    CALL OUTPUT         

    JMP QUIT

 

 

INPUT PROC ;判断是否正确输入20-30  

    JMP T1

WRONG:

    LEA DX,WRONGSTR

    mov AH,9

    INT 21H

    JMP START

T1:LEA DX,STR1

    MOV AH,9

    INT 21H

    LEA DX,INPUTBUFFER

    MOV AH,10

    INT 21H

    MOV AX,0

    MOV CL,INPUTBUFFER+1 ;?

    MOV CH,0

    LEA BX,INPUTBUFFER+2 ;?

    T2:MUL C10

    MOV DL,[BX]

    CMP DL,'0'

    JB WRONG

    CMP DL,'9'

    JA WRONG

    AND DL,0FH

    ADD AL,DL

    ADC AH,0

    INC BX

    LOOP T2

    CMP AX,001EH;判断是否比30大

    JA WRONG

    CMP AX,0014H;判断是否比20小

    JB WRONG

    CMP AX,1

    JB WRONG

    MOV N,AX

    RET

    INPUT ENDP

   

   

FIB PROC       

    CMP N,1      

    JZ L1      

    CMP N,2      

    JZ L2

    DEC N

    CALL FIB      

    MOV AX,RESULT2L      

    MOV DX,RESULT2H      

    MOV CX,RESULT1L      

    ADD RESULT2L,CX      

    MOV CX,RESULT1H      

    ADC RESULT2H,CX      

    MOV RESULT1L,AX      

    MOV RESULT1H,DX      

    JMP EXIT   

    L1:MOV RESULT1L,1       

    MOV RESULT2L,1     

    JMP EXIT   

    L2:MOV RESULT2L,1       

    DEC N       

    CALL FIB     

    EXIT:RET 

    FIB ENDP

   

   

OUTPUTPROC      

    MOV AX,RESULT2L      

    LEA SI,OUTPUTBUFFER      

    MOV CX,5 ;二进制的16位65536十进制的五位 

    LO:MOV DX,0                ;低位加入OUTPUTBUFFER      

    DIV C10      

    INC SI      

    ADD [SI],DL       ;dl为余数,最低位,要一位一位地放

    LOOP LO

   

    MOV AX,RESULT2H         

    LEA SI,OUTPUTBUFFER         

    MOV CX,5        

    HI:MOV DX,0         

    DIV C10         

    INC SI ;起始位在调整,即每次循环都要乘以10 

    PUSH CX                   ;高位加入OUTPUTBUFFER         

    CMP DX,0         

    JE NOADD ;dx为余数,余数不为0时要加上65536        

    MOV CX,DX ;dx为高位的余数,dx为几就要加上几个65536

    ADDN:CALL ADD65536          

    LOOP ADDN

    NOADD:POP CX          

    LOOP HI

   

    LEA DX,STR2      

    MOV AH,9      

    INT 21H      

    LEA SI,OUTPUTBUFFER         

    MOV BX,10      

    R3:CMP BYTE PTR [SI+BX],'0'    

    JA PRINT      

    DEC BX ;si为起始地址,bx为偏移地址                         

    JMP R3  

    PRINT:MOV DL,[SI+BX]           

    MOV AH,2          

    INT 21H          

    DEC BX          

    CMP BX,1        

    JAE PRINT                 

    RET 

    OUTPUT ENDP

   

ADD65536PROC  ;高位每一个都要加上一个加上65536         

    ADD BYTE PTR [SI],6         

    MOV DL,0      

    CMP BYTE PTR [SI],3AH             

    JB w1      

    SUB BYTE PTR [SI],10         

    MOV DL,1   

    w1:ADD BYTE PTR [SI+1],3       

    ADDBYTE PTR [SI+1],DL         

    MOV DL,0      

    CMP BYTE PTR [SI+1],3AH            

    JB w2      

    SUB BYTE PTR [SI+1],10         

    MOV DL,1     

    w2:ADD BYTE PTR [SI+2],5       

    ADD BYTE PTR [SI+2],DL       

    MOV DL,0      

    CMP BYTE PTR [SI+2],3AH             

    JB w3      

    SUB BYTE PTR [SI+2],10         

    MOV DL,1

    w3:ADD BYTE PTR [SI+3],5       

    ADD BYTE PTR [SI+3],DL         

    MOV DL,0      

    CMP BYTE PTR [SI+3],3AH           

    JB w4      

    SUB BYTE PTR [SI+3],10         

    MOV DL,1    

    w4:ADD BYTE PTR [SI+4],6       

    ADD BYTE PTR [SI+4],DL       

    MOV DL,0      

    CMP BYTE PTR [SI+4],3AH             

    JB A0      

    SUB BYTE PTR [SI+4],10         

    MOVDL,1

    w5:ADD BYTE PTR [SI+5],DL ;初始时只有前五位有数值        

    MOV DL,0      

    CMP BYTE PTR [SI+5],3AH     

    JB A0      

    SUB BYTE PTR [SI+5],10         

    MOV DL,1         

    w6:ADD BYTE PTR [SI+6],DL            

    MOV DL,0      

    CMP BYTE PTR [SI+6],3AH             

    JB A0      

    SUB BYTE PTR [SI+6],10         

    MOV DL,1   

    w7:ADD BYTE PTR [SI+7],DL            

    MOV DL,0      

    CMP BYTE PTR [SI+7],3AH            

    JB A0          

    SUB BYTE PTR [SI+7],10         

    MOV DL,1   

    w8:ADD BYTE PTR [SI+8],DL            

    MOV DL,0      

    CMP BYTE PTR [SI+8],3AH            

    JB A0      

    SUB BYTE PTR [SI+8],10         

    MOV DL,1     

    w9:ADD BYTE PTR [SI+9],DL                

    A0:RET  

    ADD65536 ENDP      

QUIT: MOVAH,4CH    

    INT 21H   

CODES ENDS

    END START


问题3:编写一拷贝程序,要求在命令行指定源文件名和目标文件名。

分析过程:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

代码分析:首先在数据段定义一个缓冲区用来接收源文件名和目的文件名,并定义提示相关信息的字符串。

然后再主程序段中主要调用了编号为3C(建立文件),3D(打开文件),3E(关闭文件),3F(读文件),40(写文件)的DOS功能。

运行结果截图:

首先,创建一个文件命名为1.txt,并添加文字

 

 

 

 

然后进行复制操作:

 

之后的结果:

 

 

 

可以看出,程序成功复制了文件。

 

 

完整代码如下所示:

DATAS SEGMENT

INFOR1  DB'Please input the  goal file:$'

INFOR2 DB 'Please input the  source file:$' 

INFOR3 DB 'Copy successfully!$'                           

ERROR1 DB 'Can not open the file! Please make surewhether the source file is exit!',07H,'$' 

ERROR2 DB 'Can not creat the file!',07H,'$'

ERROR3 DB 'Reading error!',07H,'$' 

ERROR4 DB 'Writing error!',07H,'$'     

HANDLE1 DW 0

HANDLE2  DW0  

BUFFER DB 50 

       DB? 

       DB50  DUP (0)  

DATAS ENDS

 

STACKS SEGMENT

    ;此处输入堆栈段代码

STACKS ENDS

 

CODES SEGMENT

    ASSUMECS:CODES,DS:DATAS,SS:STACKS

START:

    MOVAX,DATAS

    MOV DS,AX

    ;此处输入代码段代码

    MOV DX,OFFSET  INFOR2 

    MOVAH,9H               

    INT21H   

    MOVDX,OFFSET  BUFFER

    MOVAH,0AH

    INT21H 

    push AX

    pushDX                

    MOV   DL,0DH         

    MOV   AH,2                   

    INT   21H         

    MOV   DL,0AH        

    MOV   AH,2        

    INT   21H        

    POP   DX        

    POP   AX                    

    LEASI,BUFFER              

    MOVAL,[SI+1] 

    XORAH,AH                  

    ADDSI,2                    

    ADDSI,AX 

    MOVBYTE  PTR [SI],0  

    MOVDX,OFFSET BUFFER+2    

    MOVAX,3D00H 

    INT21H 

    JNCOPEN                

    MOVDX,OFFSET  ERROR1 

    MOVAH,9H               

    INT21H 

    JMP OVER

   

OPEN: MOV HANDLE1,AX 

        MOVDX,OFFSET  INFOR1 

        MOVAH,9H                

        INT21H  

        MOVDX,OFFSET  BUFFER 

        MOVAH,0AH 

        INT21H 

        pushAX

        pushDX                

       MOV   DL,0DH         

       MOV   AH,2              ;显示输出         

       INT   21H         

       MOV   DL,0AH        

       MOV   AH,2        

       INT   21H        

       POP   DX        

       POP   AX       

        LEASI,BUFFER          

        MOVAL,[SI+1]

        XORAH,AH 

        ADD SI,2 

        ADDSI,AX 

        MOVBYTE  PTR [SI],0

        MOVDX,OFFSET BUFFER+2  

        MOVCX,0    

        MOVAH,3CH               ;建立文件 

        INT21H 

        JNCCREAOK     ;cf为一时溢出,复制错误

        MOVBX,HANDLE1  

        MOVAH,3EH               ;关闭文件 

        INT21H 

        MOVDX,OFFSET  ERROR2 

        MOVAH,9H                 ;输入字符串 

        INT21H 

        JMPOVER

          

CREAOK: MOV HANDLE2,AX

CONT: MOV DX,OFFSET BUFFER 

      MOVCX,50      

      MOVBX,HANDLE1 

      MOVAH,3FH                ;读文件 

      INT21H 

      JCREADERR 

      ORAX,AX                    

      JZCOPY 

      MOVCX,AX 

      MOVBX,HANDLE2 

      MOVAH,40H                 ;写文件 

      INT21H 

      JCWRITERR 

      JMP CONT

     

READERR:MOV SI,OFFSET  ERROR3 

        MOVAH,9H                  

        INT21H  

        JMPCOPY 

WRITERR:MOV SI,OFFSET  ERROR4 

        MOVAH,9H                  

        INT21H 

COPY:MOV BX,HANDLE1 

        MOVAH,3EH 

        INT 21H 

        MOVBX,HANDLE2

        MOVAH,3EH               ;关闭文件 

        INT21H 

        MOVDX,OFFSET INFOR3 

        MOVAH,9H                  

        INT21H 

OVER:   MOVAH,4CH 

        INT21H

                    

CODES ENDS

    END START

 

 

题目二:

虚拟平台的模型机实验,

1. 实验目的

1)  掌握模型机的基本原理和结构

2)  掌握机器指令与微程序的对应关系;

3)   掌握机器指令的执行流程;

2. 实验设备

74LS181芯片两片,memory 6116一片,微程序控制存储器芯片一片,编译器芯片一片,八位同步计数器芯片一片,ALU_G芯片一片,PC_G芯片一片,74LS273芯片若干,输入,输出芯片各一片,选择器芯片若干,连接器芯片若干,灯泡若干,开关若干等。

3. 实验原理

图1 模型机示意图

图1中所示模型机包括运算器、存储器、微控器、输入设备、输出设备以及寄存器。这些部件的动作控制信号都有微控器根据微指令产生。需要特别说明的是由机器指令构成的程序存放在存储器中,而每条机器指令对应的微程序存储在微控器中的存储器中。模型机详细原理见附件。    

4. 实验内容

1)  选择实验设备,将所需要的组件从组件列表中拖到实验设计流程栏中

2)  搭建实验流程:根据原理图1和电路图(见附件),将已选择的组件进行连线。

3)  输入机器指令:选择菜单中的“工具”,再选择“模型机调试”,在指令输入窗口中输入如下指令:

00000000

00010000

00001001

00100000

00001011

00110000

 

实验分析与结果截图:

 

 

 

实验时的电路图如下所示:

 

下面是运行指令时的截图:

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值