了解和掌握PSP中的信息分布就是为了利用其信息。对于EXE文件,可用中断21H之功能51H获取其段地址。如:
MOV AH, 51H INT 21H ;BX=PSP的段地址 MOV ES, BX CMP byte ptr ES:[80H], 0 ;检查PSP的长度 JE next …
对于COM文件,因为其只有一个段,所以,可用更简单的方式来检查PSP的内容。
MOV BX, 80H CMP byte ptr [BX], 0 ;检查PSP的长度 JE next …
解:
DSEG SEGMENT
MSG DB "Hello$"
DSEG ENDS
CSEG SEGMENT 'CODE'
ASSUME CS:CSEG, DS:DSEG
MAIN PROC FAR
start: ;在装入内存时,DS存放的是PSP的段地址
PUSH DS
XOR AX, AX
PUSH AX ;当前堆栈内容为0和PSP的段地址
MOV AX, DSEG
MOV DS, AX
MOV DX, OFFSET MSG
MOV AH, 9
INT 21H
RET
MAIN ENDP
CSEG ENDS
END start
例10.17是早期利用PSP来终止程序的方法。子程序MAIN必须定义为FAR类型,其前三条语句是为用PSP的头二个字节来终止程序运行服务的,但现在通常用中断21H之功能4CH来终止程序的运行。
解:在使用命令行时,操作系统通常允许在被装入的程序名之后附加多达127个字符(包括最后的回车符)作为其命令的参数。
本例子的目的就是要了解命令行参数的存储方法,为以后使用命令行参数作准备。
.MODEL SMALL .CODE .STARTUP MOV AH, 51H INT 21H MOV DS, BX ;DS=PSP的段地址 MOV BX, 80H MOV CL, [BX] XOR CH, CH JCXZ over INC BX ;80~FFH字段中的跳过第二个字节 .REPEAT INC BX MOV DL, [BX] MOV AH, 2 INT 21H .UNTILCXZ ;显示命令行参数中的字符 over: .EXIT 0 END
……>type 文件1,文件2,…
其功能是分别显示其参数文件1、文件2等内容,在显示文件内容前先显示文件名。显示完内容后,暂停,等待用户按任意键。若某文件不存在,则显示相应的提示信息。
解:为了较好地解答本题,我们可以对该问题按以下步骤来解决:
.MODEL SMALL, C
.DATA
File
DB 14 DUP(' ')
Buff
DB 128 DUP(0)
Msg1
DB 0DH, 0AH, "$"
Msg2
DB "Not Found$"
Msg3
DB "Press any key...$"
.CODE
;显示字符串MSG后,再进行回车、换行
DispStr PROC USES AX DX, MSG:PTR BYTE
MOV DX, MSG ;显示指定的信息
MOV AH, 09H
INT 21H
LEA DX, Msg1 ;显示回车、换行
MOV AH, 09H
INT 21H
RET
DispStr ENDP
;文件名的长度为传递参数Len。若文件不存在,则显示提示信息,否则,显示文件内容;
;完成上述操作后,等待用户按键
Disp PROC USES AX BX CX DX, Len:BYTE
XOR BX, BX
MOV BL, Len
MOV File[BX], '$'
INVOKE DispStr, ADDR File ;显示文件名
MOV File[BX],0
LEA DX, File
MOV AL, 0H
MOV AH, 3DH
INT 21H
.IF CARRY? ;若创建失败,则显示失败信息
INVOKE DispStr, ADDR Msg2
JMP
over1
.ENDIF
MOV BX, AX ;参见例8.14中的有关说明
read:
LEA DX, Buff
MOV CX, 128
MOV AH, 3FH
INT 21H
.IF CARRY? || AX==0
JZ
close
.ENDIF
PUSH BX
LEA DX, Buff
MOV CX, AX
MOV BX, 1
MOV AH, 40H
INT 21H
POP BX
JMP read
close:
MOV AH, 3EH ;关闭已打开的文件
INT 21H
over1:
INVOKE DispStr, ADDR Msg3 ;显示等待用户按键提示信息
MOV AH, 07H
INT 21H ;等待用户按键
RET
Disp ENDP
.STARTUP
MOV AH, 51H
INT 21H
MOV ES, BX
MOV BX, 80H
MOV CL, ES:[BX]
DEC CL
INC BX
.WHILE CL>0 ;CL=未被处理的参数字符数
XOR
AL, AL ;记录文件名的长度
LEA
DI, File
.REPEAT
INC
BX
MOV
AH, ES:[BX]
DEC
CL
.BREAK .IF AH==','
MOV
[DI], AH ;从参数中分离出字符,存入文件名中
INC
DI
INC
AL
.UNTIL
CL==0
INVOKE
Disp, AL ;处理当前分离出来的文件名
.ENDW
.EXIT 0
END