马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 老刘001 于 2017-6-11 12:26 编辑
终于学完了Call&Ret
自己动手写了3个王爽&甲鱼老师要求的函数块……
DEBUG 2小时……
DivDW.ASMDivDW: ;至少需要6Byte栈空间
;参数:
;(DX)=DW型被除数高16位
;(AX)=DW型被除数低16位
;(CX)=W型除数
;返回:
;(DX)=DW型商的高16位
;(AX)=DW型商的低16位
;(CX)=余数
;一阶段:int(H/N)的计算
PUSH BX ;BX可用
PUSH AX
MOV AX,DX
SUB DX,DX ;(DX)=0
DIV CX ;(AX)=商 (DX)=余数
MOV BX,AX
POP AX ;(AX)=DW型被除数低16位
PUSH BX ;备份int(H/N)
;此时 (AX)=DW型被除数低16位 (DX)=余数=rem(H/N)
;二阶段:(rem(H/N)*FFFFH+L)/N的计算以及收尾工作
DIV CX ;(DX)=余数 (AX)=商
MOV CX,DX ;(CX)=(DX)=余数
POP DX
POP BX ;还原BX
RET
DtoC.ASM 这个是双字版的,当时看到后面还要重写双字版就决定直接写双字版了DtoC: ;必须和DivDW函数块一起使用,栈空间至少20Byte。
;功能:将Dword型数转变为十进制数的字符串,以0结尾。
;参数:
;(AX)=DW型数据的低16位
;(DX)=DW型数据的高16位
;DS:SI指向字符串的首地址。
;返回:DS:SI原位置被字符串覆盖,以0结尾,AX,DX被清零。
PUSH SI
PUSH CX ;备份CX
PUSH BX ;备份BX
PUSH DI ;备份DI
PUSH SI ;再次备份初始地址SI
XOR DI,DI
XOR BX,BX
DtoC_Loop1:
MOV CX,0AH
CALL DivDW
ADD CL,30H
MOV [SI],CL
MOV CX,AX
JCXZ DtoC_Judge
INC SI
INC BX
JMP DtoC_Loop1
DtoC_Judge:
MOV CX,DX
JCXZ DtoC_Next
INC SI
INC BX
JMP DtoC_Loop1
DtoC_Next:
POP SI
PUSH SI
PUSH BX
MOV CX,BX
MOV DI,BX
INC CX
DtoC_Loop2: ;备份并翻转
MOV BX,CX
SUB BX,1
MOV AL,[BX+SI]
MOV BX,DI
MOV [BX+SI+1],AL
INC DI
LOOP DtoC_Loop2
POP BX
POP SI
MOV CX,BX
INC CX
DtoC_Loop3: ;还原
MOV AL,[BX+SI+1]
MOV [SI],AL
INC SI
LOOP DtoC_Loop3
;收尾
MOV BYTE PTR [BX+1],0
POP DI
POP BX
POP CX
SUB AX,AX
XOR DX,DX
POP SI
RET
show_str.ASM ;栈空间至少10Byte
SHOW_STR: ;功能:显示DS开头的字符串,以0结尾。
;参数:
;(DH)=屏幕缓存区的行号(范围1-25)
;(DL)=列号(范围1-80)
;(CL)=颜色
PUSH AX ;备份
PUSH BX
PUSH SI
PUSH SI
XOR SI,SI
MOV AX,0B800H ;屏幕缓冲区
MOV ES,AX
XOR AX,AX
XOR BX,BX
;AX、BX、SI空闲&可用
SUB DH,1
MOV AL,DH
MOV BL,0A0H
MUL BL ;计算行的偏移
XOR DH,DH
;DH可用
SUB DL,1
ADD DX,DX ;计算列的偏移
ADD AX,DX ;得到整体偏移量
ADD SI,AX ;SI赋值为整体偏移量
XOR AX,AX ;AX空闲&可用
XOR DX,DX ;DX空闲&可用
POP BX ;BX定位内存中的字符
MOV DL,CL ;DL储存字符颜色
SUB CX,CX ;CX用来储存字符Ascii码并判断跳出
SHOW_STR_LOOP:
MOV CL,[BX]
JCXZ SHOW_STR_FINISH
MOV ES:[SI],CL
MOV ES:[SI+1],DL
ADD SI,2
INC BX
JMP SHOW_STR_LOOP
SHOW_STR_FINISH:
POP SI
POP BX
POP AX
RET
|