| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2154 人关注过本帖, 1 人收藏
标题:[讨论]程序段前缀解析
只看楼主 加入收藏
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏(1)
 问题点数:0 回复次数:8 
[讨论]程序段前缀解析

/*********************环境块内存段********************************************/ /***************************************************************************** 每次执行一个程序时,dos系统对当前环境进行备份,并将环境备份段地址提供给程序, psp环境块中包含程序备份的段地址。 下述程序利用该区域定位和显示程序的环境。 ******************************************************************************/ #include<dos.h> #include<stdio.h> int main(void) { char far *environment;/*环境块远指针*/ /*定义文件控制块结构*/ typedef struct fcbs{ /*指定包含文件的磁盘驱动器,0是当前驱动器,1是A驱动器,2是b驱动器*/ char drive; char filename[8]; /*文件名,若文件名小于8个字符,则以空格填充*/ char extension[3]; /*文件扩展名,若扩展名少于3个字符,则以空格填充*/ int current_block;/*当前记录的块的数目。每块包含128个字符*/ int record_size; /*指定以字节表示的每个记录的大小,默认为128个记录*/ }fcb; /*定义程序段前缀结构*/ struct program_segment_prefix { char near *int20; /*int 20h指令,可以终止程序*/ char near *next_paragraph_segment; /*程序后第一个段的段地址*/ char reserved_1; /*保留*/ char dos_dispatchr[5]; /*远程调用dos功能调度程序指令*/ char far *terminate_vector; /*指定程序终止DOS赋予INT 22H处理程序的向量*/ char far *ctrlc_vector; /*程序终止DOS赋予Ctrl-c INT 23H处理程序的向量*/ /*指定程序终止时DOS赋予INT 24H关键错误处理程序的向量*/ char far *criticle_error_segment;

char reserved_2[22]; /*保留*/ char near *environment_block_segment;/*程序环境拷贝的段地址*/ char reserved_3[46]; /*保留*/ fcb fcb1; /*程序的缺省文件控制块1*/ fcb fcb2; /*程序的缺省文件控制块2*/ char reserved_4[4]; /*保留*/ char command_tail[128]; /*程序的命令行*/ }far *psp; psp=(struct program_segment_prefix far *)((long)_psp<<16); environment=(char far *)((long)psp->environment_block_segment<<16); /*environment ends with double nulls \0\0*/ while((*environment!='\0')||(*(environment+1)!='\0')) { if(*environment=='\0') { printf("\n"); environment++; } else printf("%c",*environment++); } getch(); return 0; }

搜索更多相关主题的帖子: 前缀 解析 
2004-07-06 13:56
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/*************************文件控制块域************************************/ /************************************************************************** 在dos2.0以前的版本中,文件的I/O操作通过使用文件控制块(FCBs)完成。 当用户运行一个程序时,dos系统在系统中创建两个文件控制块。 dos在用户运行程序时分析命令行,并假定开头的两个命令行参数包含文件名。 dos将文件名赋给psp文件控制块。下述程序显示了赋给psp文件控制块的文件名。 **************************************************************************/ #include<dos.h> #include<stdlib.h> int main(void) { int i;

struct fcbs{ char drive; char filename[8]; char extension[3]; int current_block; int record_size; }; typedef struct fcbs fcb;

struct program_segment_prefix{ char near *int20; char near *next_paragraph_segment; char reserved_1; char dos_dispatcher[5]; char far *erminate_vector; char far *ctrlc_vector; char far *critical_error_vector; char reserved_2[22]; char near *environment_block_segment; char reserved_3[46]; fcb fcb1; fcb fcb2; char reserved_4[4]; char command_tail[128]; }far *psp;

psp=(struct program_segment_prefix far *)((long)_psp<<16); if(psp->fcb1.filename[0]!=' ') { printf("First filename");

for(i=0;i<8;i++) { if(psp->fcb1.filename!=' ') printf("%c",psp->fcb1.filename); else break; }

printf(".");

for(i=0;i<3;i++) { if(psp->fcb1.extension!=' ') printf("%c",psp->fcb1.extension); else break; } printf("\n"); } if(psp->fcb2.filename[0]!=' ') { printf("Second filename");

for(i=0;i<8;i++) { if(psp->fcb2.filename!=' ') printf("%c",psp->fcb2.filename); else break; } printf("."); for(i=0;i<3;i++) { if(psp->fcb2.extension!=' ') printf("%c",psp->fcb2.extension); else break; } } getch(); return 0; }

2004-07-06 13:57
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/****************************命令行*************************/ /*********************************************************** 当用户运行一个程序时,dos系统将程序命令行置入psp域中偏移 地址80H处。实际上,在偏移地址80H处包含命令行中字符的个数。从 偏移地址81H处开始存储命令行。 下述程序显示命令行字符个数。可用不同的命令行值调用该程序。 ************************************************************/

#include<dos.h> #include<stdlib.h> int main(void) { struct fcbs{ char driver; char filename[8]; char extension[3]; int current_block; int record_size; }; typedef struct fcbs fcb; struct program_segment_prefix{ char near *int20; char near *next_paragraph_segment; char reserved_1; char dos_dispatcher[5]; char far *terminate_vector; char far *ctrlc_vector; char far *critical_error_vector; char reserved_2[22]; char near *environment_block_segment; char reserved_3[46]; fcb fcb1; fcb fcb2; char reserved_4[4]; char command_tail[128]; }far *psp; psp=(struct program_segment_prefix far *)((long)_psp<<16); printf("The command line contains %d characters\n",psp->command_tail[0]); getch(); return 0; }

2004-07-06 13:57
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/******************显示命令行*******************/ #include<dos.h> #include<stdlib.h> int main(void) { int i;

struct fcbs{ char driver; char filename[8]; char extension[3]; int current_block; int record_size; };

typedef struct fcbs fcb;

struct program_segment_prefix{ char near *int20; char near *next_paragraph_segment; char reserved_1; char dos_dispatcher[5]; char far *terminate_vector; char far *ctrlc_vector; char far *critical_error_vector; char reserved_2[22]; char near *environment_block_segment; char reserved_3[46]; fcb fcb1; fcb fcb2; char reserved_4[4]; char command_tail[128]; }far *psp;

psp=(struct program_segment_prefix far *)((long)_psp<<16);

for(i=1;i<=psp->command_tail[0];i++) { printf("%c",psp->command_tail); } getch(); return 0; }

2004-07-06 13:58
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/******************************************************************************* dos系统总是紧接命令行最后一个字符后放入一个回车键字符(0Dh), 存储在偏移地址80h处的字符数不包括换行键字符。下述程序显示到回车键 字符处的命令行字符的个数。 使用同样技术,可以分析命令行参数。事实上,就是c程序如何使用 argr[]访问命令行。在程序代码之前,c编译程序插入分析和将命令行赋值 给argv[]的代码。如果考虑字符计数要去掉一个字节的事实,那么除回车符 外,dos可支持的最长命令行为126个字节。 依据缺省值,注意到dos使用从程序段前缀中偏移地址80H处开始的128 个字节,将之作为磁盘传送区域。因输入输出使用文件控制块的程序通过磁盘 传送区域传送数据。如果创建一个使用文本控制块的程序,用户需要首先保留 命令行;否则:第一个基于文件控制块的输入输出操作可能改写它。 *********************************************************************************/ #include<dos.h> #include<stdlib.h> int main(void) { int i;

struct fcbs{ char driver; char filename[8]; char extension[3]; int current_block; int record_size; };

typedef struct fcbs fcb;

struct program_segment_prefix{ char near *int20; char near *next_paragraph_segment; char reserved_1; char dos_dispatcher[5]; char far *terminate_vector; char far *ctrlc_vector; char far *critical_error_vector; char reserved_2[22]; char near *environment_block_segment; char reserver_3[46]; fcb fcb1; fcb fcb2; char reserved_4[4]; char command_tail[128]; }far *psp;

psp=(struct program_segment_prefix far *)((long)_psp<<16); for(i=1;psp->command_tail!=0xD;i++) printf("%c",psp->command_tail);

getch(); return 0;

}

2004-07-06 13:59
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/**************************程序段前缀的全面描述****************************/ /*************************************************************************** 内存偏移地址: oh int 20H指令 2h 下一段的段地址 4h 保留 5h 远调用dos调度程序 ah Int 22h向量 eh int 23h向量 12h int 24h向量 16h 父程序psp段 18h 系统文件表项 2ch 环境备份段地址 2eh dos ss:sp存储区 32h 文件句柄计数区 34h 文件句柄指针 38h SHARE前PSP域 3ch 保留 50h 远调用DOS调度程序 52h 保留 5ch 缺省FCB1 6ch 缺省FCB2 7ch 保留 80h 命令行字节长度 81h 命令行 ffh *****************************************************************************/ /**************************************************************************** 当一个程序使用系统服务调用另一个程序时,新的程序称为子程序,而上一个程序称为 父程序。父子两个程序都保存在内存中,父程序psp段域包含父程序段前缀的段地址。 下述程序使用该域显示激活程序的数量。 dos的外壳程序command.com不在其中,只包含其子程序 。 *****************************************************************************/

#include<dos.h> #include<stdlib.h> int main(void) {

struct fcbs{ char drive; char filename[8]; char extension[3]; int current_block; int record_size; };

typedef struct fcbs fcb;

struct program_segment_prefix{ char near *int20; /*int 20H指令*/ char near *next_paragraph_segment; /*下一段的段地址*/ char reserved_1; /*保留*/ char dos_dispatcher[5]; /*远调用dos调度程序*/ char far *terminate_vector; /*Int 22h向量*/ char far *ctrlc_vector; /*int 23h向量*/ char far *critical_error_vector; /*int 24h向量*/ char near *parent_psp; /*父程序psp段*/ unsigned char file_table[20]; /*系统文件表项*/ char near *environment_block_segment;/*环境备份段地址*/ char far *stack_storage; /*dos ss:sp存储区*/ int handles_available; /*文件句柄计数区*/ char far *file_table_address; /*文件句柄指针*/ char far *shares_previous_psp; /*SHARE前PSP域*/ char reserved_2[20]; /*保留*/ char dos_int21_retf[3]; /*远调用DOS调度程序*/ char reserved_3[9]; /*保留*/ fcb fcb1; /*缺省FCB1*/ fcb fcb2; /*缺省FCB2*/ char reserved_4[4]; /*保留*/ char command_tail[128]; /*命令行*/ }far *psp,far *parent_psp; int child_count=0;

psp=(struct program_segment_prefix far *)((long)_psp<<16); parent_psp=(struct program_segment_prefix far *) ((long)psp->parent_psp<<16);

do { child_count++; psp=parent_psp; parent_psp=(struct program_segment_prefix far *) ((long)psp->parent_psp<<16); }while(psp!=parent_psp);

printf("Number of children %d\n",child_count);

getch(); return 0; }

2004-07-06 14:00
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/************************************************************************* 当程序打开一个文件时,dos系统将一个文件句柄赋给该文件,并返回文件句柄 为程序使用。当用户程序运行时,dos需要保存查找文件的路径。这样,dos在程序 段前缀中开辟一段区域作为程序文件表区。该区域可包含20个文件句柄的信息。作业 文件表的值,实际上对应于dos系统文件表的项,这些内容将在第12章“磁盘服务” 中论述。依据缺省值,dos初始化对应于标准设备的5个项(stdin,stdout,stderror, stdaux和stdprn).下述程序显示程序文件表中当前使用的文件句柄数。如果一项未被 使用,其值为FFH. **************************************************************************/ #include<dos.h> #include<stdlib.h> int main(void) { struct fcbs{ char drive; char filename[8]; char extension[3]; int current_block; int record_size; }; typedef struct fcbs fcb; struct program_segment_prefix{ char near *int20; char near *next_paragraph_segment; char reserved_1; char dos_dispatcher[5]; char far *terminate_vector; char far *ctrlc_vector; char far *critical_error_vector; char near *parent_psp; unsigned char file_table[20]; char near *environment_block_segment; char far *stack_storage; int handles_available; char far *shares_previous_psp; char reserved_2[20]; char dos_int21_retf[3]; char reserved_3[9]; fcb fcb1; fcb fcb2; char reserved_4[4]; char command_tail[128]; }far *psp; int i,file_count=0; psp=(struct program_segment_prefix far *) ((long)_psp<<16); for(i=0;i<20;i++) { if(psp->file_table!=0xFF) file_count++; } printf("The number of files in use %d\n",file_count);

getch(); return 0; }

2004-07-06 14:01
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/***********************堆栈段和指针存储区域****************************/ /************************************************************************ dos系统利用该域存储当前程序堆栈段地址和堆栈指针。从概念上来说,在psp 区域中存储堆栈指针和段地址的处理类似于在一个处理控制块中存储处理信息的多 任务操作系统。 正如dos系统利用程序文件表查找一个程序文件。psp的文件句柄项查找程序文件表 项总数。下述程序先使用可用文件句柄域显示程序文件句柄缺省数(20个文件句柄) 然后,利用Int 21h功能67h将文件句柄数增加到50个,并显示psp的文件句柄域中的 修改后的值。 ************************************************************************/ #include<dos.h> #include<stdio.h> int main(void) { struct fcbs{ char drive; char filename[8]; char extension[3]; int current_block; int record_size; }; typedef struct fcbs fcb; struct program_segment_prefix{ char near *int20; char near *next_paragraph_segment; char reserved_1; char dos_dispatcher[5]; char far *terminate_vector; char far *ctrlc_vector; char far *critical_error_vector; char near *parent_psp; unsigned char file_table[20]; char near *environment_block_segment; char far *stack_storage; int handles_available; char far *file_table_address; char far *shares_previous_psp; char reserved_2[20]; char dos_int21_retf[3]; char reserved_3[9]; fcb fcb1; fcb fcb2; char reserved_4[4]; char command_tail[128]; }far *psp; union REGS inregs,outregs; psp=(struct program_segment_prefix far *)((long)_psp<<16); printf("Default Number of Handles %d\n",psp->handles_available); /*change the number of handles to 50*/ inregs.h.ah=0x67; inregs.x.bx=50; intdos(&inregs,&outregs); printf("New Number of Handles %d\n",psp->handles_available);

getch(); return 0; }

2004-07-06 14:01
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

/***********************文件表指针*******************************/ /***************************************************************** 如果用户要求多于20个文件句柄,可使用INT 21H功能67H增加可用文件 句柄数。当调用该功能时,dos将工作文件表移至一新位置。psp文件表区包 含程序文件表地址。根据缺省值,该域在psp中偏移到18H处。下述程序使用 该域首先显示当前程序文件表地址。然后将所需文件句柄数增至50个并再显 示文件表的新地址。 *****************************************************************/ /***NOTE:compile this program using the large memory model!******/ #include<dos.h> #include<stdlib.h> int main(void) { struct fcbs{ char drive; char filename[8]; char extension[3]; int current_block; int record_size; }; typedef struct fcbs fcb; struct program_segment_prefix{ char near *int20; char near *next_paragraph_segment; char reserved_1; char dos_dispatcher[5]; char far *terminate_vector; char far *ctrlc_vector; char far *critical_error_vector; char near *parent_psp; unsigned char file_table[20]; char near *environment_block_segment; char far *stack_storage; int handles_available; char far *file_table_address; char far *shares_previous_psp; char reserved_2[20]; char dos_int21_retf[3]; fcb fcb1; fcb fcb2; char reserved_4[4]; char command_tail[128]; }far *psp; union REGS inregs,outregs; psp=(struct program_segment_prefix far *)((long)_psp<<16); printf("original file table address %p\n",psp->file_table_address);

/*change the number of handles to 50*/ inregs.h.ah=0x67; inregs.x.bx=50; intdos(&inregs,&outregs); printf("Ending file table address %p\n",psp->file_table_address);

getch(); return 0; }

2004-07-06 14:01
快速回复:[讨论]程序段前缀解析
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018922 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved