实验二 函数和高级汇编程序设计
实验目的
1、 掌握函数的编写及通过堆栈传递参数的方法,。
2、掌握中断服务子程序的编写。
实验内容
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、编写一个子程序计算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