汇编实验二(自己思考如何修改代码,有注释的地方就是关键)

实验二 函数和高级汇编程序设计

  1. 实验目的

1、 掌握函数的编写及通过堆栈传递参数的方法,。

2、掌握中断服务子程序的编写。

  1. 实验内容

1、编写一个子程序计算z=f(x,y)=x*y -2x+2022(x,y,z有符号数字变量),要求:

(1)假设x*y的结果还是16位;

(2)输入参数通过堆栈传送,输出参数通过AX传送;

(3)主程序调用后,结果需要输出到屏幕上。

2、挂接1CH中断,正计时30秒后退出。要求屏幕显示0-29的秒数。(选做)

  1. 实验过程和程序

1、编写一个子程序计算z=f(x,y)=x*y -2x+2022(x,y,z有符号数字变量),要求:

(1)假设x*y的结果还是16位;

(2)输入参数通过堆栈传送,输出参数通过AX传送;

(3)主程序调用后,结果需要输出到屏幕上。

STACK SEGMENT STACK
    DW 512(?)
STACK ENDS
DATA SEGMENT
    X DW 3                ;默认x为3,y为5,计算结果z为2032
    Y DW 5
    Z DW 0
DATA ENDS
CODE SEGMENT
    ASSUME CS:CODE,DS:DATA,SS:STACK
START:
    MOV AX,DATA
    MOV DS,AX
    
    PUSH X
    PUSH Y
    CALL COUNT    ;调用计算函数
    MOV Z,AX    ;寄存器将结果返回,保存在Z中
    CALL SHOW    ;调用显示结果函数
    
    MOV AX,4C00H
    INT 21H

COUNT PROC
    PUSH BP
    MOV BP,SP
    PUSH BX
    PUSH DX        ;保存现场
    
    MOV AX,[BP+4]    ;Y
    MOV BX,[BP+6]    ;X
    IMUL BX        ;AX=X*Y
    SUB AX,BX    ;AX=X*Y-X
    SUB AX,BX    ;AX=X*Y-2X
    ADD AX,2022    ;AX=X*Y-2X+2022

    POP DX        ;还原现场
    POP BX
    POP BP
    RET 4        ;程序返回,跳过参数X,Y
COUNT ENDP    ;程序结束

SHOW PROC
    PUSH BX
    PUSH DX
    
    TEST AX,AX
    JNZ SHOW1
    MOV DL,'0'    ;如果结果是0
    MOV AH,02H
    INT 21H
    JMP DOWN

SHOW1:    
    JNS SHOW2    ;如果是正数就转移
    MOV BX,AX    ;如果是负数,暂存AX
    MOV DL,'-'    ;输出负号
    MOV AH,2
    INT 21H
    NEG BX        ;数据求补(绝对值)
    MOV BX,AX

SHOW2:
    MOV BX,10    ;存入退出标志
    PUSH BX
    
AGAIN1:
    CMP AX,0
    JZ AGAIN2    ;跳到输出循环中
    MOV DX,0    ;扩展被除数    
    DIV BX        
    ADD DL,30H
    PUSH DX
    JMP AGAIN1

AGAIN2:
    POP DX
    CMP DL,10
    JE DOWN
    MOV AH,2
    INT 21H
    JMP AGAIN2

DOWN:    POP DX
    POP BX
    RET
SHOW ENDP

CODE ENDS
    END START

2、挂接1CH中断,正计时30秒后退出。要求屏幕显示0-29的秒数。(选做)

 INTNO EQU 1CH
    
    DATA SEGMENT
      OLDISR DW ?,?
      TIMER DB 100
      COUNTER DW 0    ;从0开始
      ISDONE DB 0
    DATA ENDS
    
    CODE SEGMENT
      ASSUME CS:CODE,DS:DATA
START:
      MOV AX,DATA
      MOV DS,AX
      
      MOV AX,0
      MOV ES,AX
      
      ;PROTECT
   
      CLI
      MOV AX, ES:[INTNO*4]
      MOV OLDISR[0],AX
      MOV AX,ES:[INTNO*4+2]
      MOV OLDISR[2], AX
      STI
    
      ;SET NEW ISR
    
      CLI
      MOV WORD PTR ES:[INTNO*4], OFFSET ISR
      MOV WORD PTR ES:[INTNO*4+2],SEG ISR
      STI


    ;WAIT HERE
WAITHERE:
    CMP ISDONE,1
    JNZ WAITHERE
  
  
EXIT:     
    ;RESTORE
   
      CLI
      MOV AX,OLDISR[0]
      MOV ES:[INTNO*4],AX
      MOV AX,OLDISR[2]
      MOV ES:[INTNO*4+2],AX
      STI
        
      MOV AX,4C00H
      INT 21H
      
ISR PROC FAR
        PUSH DX
        PUSH AX
        
        MOV AX,DATA
        MOV DS,AX

        STI               ;便于中断嵌套

       ;COUNT HERE
        INC TIMER
AGAIN:
        CMP TIMER, 1000/55  ;18
        JB DONE
        MOV TIMER,0


        ;carriage
        MOV AH,2
        MOV DL,13
        INT 21H

    MOV AH,2
        MOV DL,10
        INT 21H
        ;print time
        MOV AX,COUNTER

        MOV DL,10
        DIV DL
        MOV DH,AH
        MOV DL,AL
        MOV AH,2
        ADD DL,30H
        INT 21H
        MOV DL,DH
        ADD DL,30H
        INT 21H
        
        INC COUNTER
        CMP COUNTER,30    
    JNE DONE    ;没到30就继续
        MOV ISDONE,1
        
DONE:
        PUSHF
        CALL DWORD PTR OLDISR

        CLI
        POP AX
        POP DX
        IRET             ;中断返回
ISR ENDP


CODE ENDS
      END START

你可能感兴趣的:(汇编)