灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:1827回复:0

程序段前缀的应用

楼主#
更多 发布于:2012-09-10 18:55

了解和掌握PSP中的信息分布就是为了利用其信息。对于EXE文件,可用中断21H之功能51H获取其段地址。如:

MOVAH, 51H

INT21H;BX=PSP的段地址

MOV ES, BX

CMP byte ptr ES:[80H], 0;检查PSP的长度

JEnext



对于COM文件,因为其只有一个段,所以,可用更简单的方式来检查PSP的内容。

MOV BX, 80H

CMPbyte ptr [BX], 0;检查PSP的长度

JEnext



例10.17 利用PSP中的信息来终止当前程序的运行。

解:

DSEGSEGMENT

MSG DB "Hello$"

DSEGENDS

CSEGSEGMENT ’CODE’

ASSUME CS:CSEG, DS:DSEG

MAINPROC FAR

start:;在装入内存时,DS存放的是PSP的段地址

PUSHDS

XORAX, AX

PUSHAX;当前堆栈内容为0和PSP的段地址

MOVAX, DSEG

MOVDS, AX

MOVDX, OFFSET MSG

MOVAH, 9

INT21H

RET

MAINENDP

CSEGENDS

END start

例10.17是早期利用PSP来终止程序的方法。子程序MAIN必须定义为FAR类型,其前三条语句是为用PSP的头二个字节来终止程序运行服务的,但现在通常用中断21H之功能4CH来终止程序的运行。

例10.18 编写程序,显示其命令行参数信息。

解:在使用命令行时,操作系统允许在被装入的程序名之后附加多达127个字符(包括最后的回车符)作为其命令的参数。

本例子的目的就是要了解命令行参数的存储方法,为以后使用命令行参数作准备。

.MODEL SMALL

.CODE

.STARTUP

MOVAH, 51H

INT21H

MOV DS, BX;DS=PSP的段地址

MOVBX, 80H

MOV CL, [BX]

XOR CH, CH

JCXZ over

INC BX;80~FFH字段中的跳过第二个字节

.REPEAT

INCBX

MOVDL, [BX]

MOVAH, 2

INT21H

.UNTILCXZ;显示命令行参数中的字符

over:

.EXIT 0

END

例10.19 编写一个类型于DOS内部命令TYPE的程序,该命令的使用方法如下:

……>type 文件1,文件2,…

其功能是分别显示其参数文件1、文件2等内容,在显示文件内容前先显示文件名。显示完内容后,暂停,等待用户按任意键。若某文件不存在,则显示相应的提示信息。

解:为了较好地解答本题,我们可以对该问题按以下步骤来解决:

1、若命令行参数中的字符数为0,则结束本程序的运行;

2、从命令行参数中分离出一个文件名;

3、调用子程序,显示当前文件名、文件内容和等待用户按键;

4、重复步骤1~3,直到所有参数被处理完。

.MODEL SMALL, C

.DATA

FileDB 14 DUP(’ ’)

Buff DB 128 DUP(0)

Msg1DB 0DH, 0AH, "$"

Msg2DB "Not Found$"

Msg3DB "Press any key...$"

.CODE

;显示字符串MSG后,再进行回车、换行

DispStrPROC USES AX DX, MSG:PTR BYTE

MOVDX, MSG;显示指定的信息

MOVAH, 09H

INT21H

LEADX, Msg1;显示回车、换行

MOVAH, 09H

INT21H

RET

DispStrENDP

;文件名的长度为传递参数Len。若文件不存在,则显示提示信息,否则,显示文件内容;

;完成上述操作后,等待用户按键

DispPROC USES AX BX CX DX, Len:BYTE

XORBX, BX

MOVBL, Len

MOVFile[BX], ’$’

INVOKEDispStr, ADDR File;显示文件名

MOVFile[BX],0

LEADX, File

MOVAL, 0H

MOVAH, 3DH

INT21H

.IF CARRY?;若创建失败,则显示失败信息

INVOKE DispStr, ADDR Msg2

JMPover1

.ENDIF

MOVBX, AX;参见例8.14中的有关说明

read:

LEADX, Buff

MOVCX, 128

MOVAH, 3FH

INT21H

.IF CARRY? || AX==0

JZclose

.ENDIF

PUSHBX

LEADX, Buff

MOVCX, AX

MOVBX, 1

MOVAH, 40H

INT21H

POPBX

JMPread

close:

MOVAH, 3EH;关闭已打开的文件

INT21H

over1:

INVOKEDispStr, ADDR Msg3;显示等待用户按键提示信息

MOVAH, 07H

INT21H;等待用户按键

RET

DispENDP

.STARTUP

MOVAH, 51H

INT21H

MOVES, BX

MOVBX, 80H

MOVCL, ES:[BX]

DECCL

INCBX

.WHILE CL>0;CL=未被处理的参数字符数

XORAL, AL;记录文件名的长度

LEADI, File

.REPEAT

INCBX

MOVAH, ES:[BX]

DECCL

.BREAK .IF AH==’,’

MOV[DI], AH;从参数中分离出字符,存入文件名中

INCDI

INCAL

.UNTILCL==0

INVOKEDisp, AL;处理当前分离出来的文件名

.ENDW

.EXIT 0

END

喜欢0 评分0
游客

返回顶部