- 利用递归的方法求N的阶乘。
- 十进制到十六进制的转换程序:从键盘输入一个十进制数,然后把该数以十六进制的形式显示在屏幕上。
- 调用子程序进行数组求和(不考虑溢出情况),其数组元素和结果均为字型数据。
代码一
DATAS SEGMENT
;此处输入数据段代码
N DW 6
FN DW ? ;存储阶乘结果FN
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
MOV AX,N ;N值放入AX寄存器
CALL FACT ;调用阶乘子程序
MOV FN,DX ;将DX值存储到FN
JMP EXIT ;执行结束
FACT PROC NEAR
PUSH AX ;保护现场
CMP AX,0 ;比较当前N于0的大小
JA L1 ;大于则跳转L1
MOV DX,1 ;否则直接DX=1
JMP L2 ;恢复现场,结束
L1:
PUSH AX ;保护AX
DEC AX ;AX<--N-1
CALL FACT ;调用子程序求N-1的阶乘
POP AX ;恢复AX
MUL DL ;AX<--DL*AX
MOV DX,AX ;DX<--AX 存储当前乘积值
L2:
POP AX ;恢复现场AX
RET
FACT ENDP
DPCRLF PROC ;光标回车换行子程序
PUSH AX
PUSH DX
MOV AH,2
MOV DL,0DH
INT 21H
MOV AH,2
MOV DL,0AH
INT 21H
POP DX
POP AX
RET
DPCRLF ENDP
EXIT:
MOV AH,4CH
INT 21H
CODES ENDS
END START
代码二
DATAS SEGMENT
;此处输入数据段代码
ARRAY1 DW 2,4,6,8,10,12
COUNT1 DW ($-ARRAY1)/2 ;数组元素个数
SUM1 DW ? ;数组和
ARRAY2 DW 1,3,5,7,9,11
COUNT2 DW ($-ARRAY2)/2 ;数组元素个数
SUM2 DW ? ;数组和
TABLE DW 3 DUP(?) ;地址表
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
DW 32 DUP('S') ;堆栈段定义
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
;构造地址表
MOV TABLE,OFFSET ARRAY1
MOV TABLE+2,OFFSET COUNT1
MOV TABLE+4,OFFSET SUM1
;将地址表的首地址存放到BX
LEA BX,TABLE
CALL GET_ARRAY_SUM
;构造地址表
MOV TABLE,OFFSET ARRAY2
MOV TABLE+2,OFFSET COUNT2
MOV TABLE+4,OFFSET SUM2
;将地址表的首地址存放到BX
LEA BX,TABLE
CALL GET_ARRAY_SUM
JMP EXIT
GET_ARRAY_SUM PROC
;保护现场
PUSH AX
PUSH CX
PUSH SI
PUSH DI
MOV SI,[BX] ;取数组起始地址
MOV DI,[BX+2] ;取数组元素个数地址
MOV CX,[DI] ;取数组元素个数
MOV DI,[BX+4] ;取结果地址
XOR AX,AX ;累加器清零
NEXT:
ADD AX,[SI] ;累加和
ADD SI,TYPE ARRAY1 ;修改地址指针
LOOP NEXT
MOV [DI],AX ;存和
;恢复寄存器
POP DI
POP SI
POP CX
POP AX
RET
GET_ARRAY_SUM ENDP
EXIT:
MOV AH,4CH
INT 21H
CODES ENDS
END START
代码三
DATAS SEGMENT
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
CALL DECTOHEX
JMP E
DECTOBIN PROC ;十进制到二进制,转换后的二进制数存在BX中
MOV BX,0
NEWCHAR:
MOV AH,1
INT 21H
SUB AL,30H
JL EXIT
CMP AL,9
JG EXIT
CBW
XCHG AX,BX
MOV CX,10
MUL CX
XCHG AX,BX
ADD BX,AX
JMP NEWCHAR
EXIT:
RET
DECTOBIN ENDP
BINTOHEX PROC ;二进制到十六进制并显示输出
MOV CH,4
ROTATE:
MOV CL,4
ROL BX,CL
MOV AL,BL
AND AL,0FH
ADD AL,30H
CMP AL,3AH
JL PRINTIT
ADD AL,7
PRINTIT:
MOV DL,AL
MOV AH,2
INT 21H
DEC CH
JNZ ROTATE
RET
BINTOHEX ENDP
DECTOHEX PROC ;十进制到十六进制子程序
PUSH DS
SUB AX,AX
PUSH AX
CALL DECTOBIN
CALL BINTOHEX
CALL NEWLINE
;恢复现场 不恢复造成程序死循环
POP AX
POP DS
RET
DECTOHEX ENDP
NEWLINE PROC ;回车换行
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
INT 21H
RET
NEWLINE ENDP
E:
MOV AH,4CH
INT 21H
CODES ENDS
END START
代码一
主程序:将N值存入AX做入口参数,调用子程序FACT,结果存放在DX寄存器中,最后将DX的结果转移至FN内存单元。子程序:首先保护现场,比较当前N值与0的大小,如果大于,跳转到L1执行,否则DX=1,恢复现场,程序结束。L1:首先PUSH AX进行保护,将AX-1即N-1调用子程序FACT进行递归操作,最终结果存放于DX。DPCRLF子程序为回车换行。
代码二
子程序:DECTOBIN十进制转二进制:入口参数:无,出口参数:转换后的二进制数存在BX中;BINTOHEX二进制转十六进制:入口参数:存放二进制数的BX,出口参数:无。NEWLINE子程序:回车换行。
代码三
以计算一个数组和为例,首先构造地址表TABLE:分别将数组首地址,数组元素个数和结果存储地址存放在TABLE中,将地址表TABLE的首地址存放在BX寄存器中,调用子程序GET_ARRAY_SUM求和,程序结束。子程序GET_ARRAY_SUM:首先保护现场,取数组首地址,数组元素个数,结果地址分别存放于SI,CX,DI,AX做累加器首先清零,将[SI]内容与AX相加存于AX,修改SI地址,进行循环操作,最后存入[DI],恢复现场。
图表 1 代码一测试
图表 2 代码二测试
图表 3 代码三测试