用户名: 密码: 验证码: gdcode 注册

驻留exe文件

时间:2007-06-15 来源: 作者: 【字体: 减小 增大点击: 收藏 | 投稿
  

运行重定位exe文件,重定位因子调度覆盖模块,链接器3制静态覆盖块,析栈初始startup

(1)X86汇编语言的组,段,类

伪指令group/segment,定义组/段,这使:

(1.1)同组的各段,处于同一64k空间

(1.2)段可声明'对齐,组合,类'可选属性:

(1.2.1)段首,能对齐到BYTE,WORD,PARA(16字节),PAGE(256字节),缺省对齐到PARA.
(1.2.2)不同源文的同名同类段,想靠链接,形成空间邻接或重叠的同名组合逻辑
段时,需用PUBLIC,COMMON,指明组合形式:

(1.2.2.1)PUBLIC,指明此段按对齐属性,邻在已包含在此组合逻辑段内的最末字面段之后
(1.2.2.2)COMMON,指明此段与同属此组合逻辑段的其他字面段,从组合逻辑段首铺展

同属组合逻辑段的各参与段的最大对齐属性(例如,WORD比BYTE大),决定组合逻辑段的对齐属性.

不与其它段组合的段,称为单逻辑段.

以下,用"逻辑段",统称组合逻辑段及单逻辑段.

财软联.盟.fs119.net



(1.3)类用'cls'指明,未指明类的各段,属'匿名'类.同类各段,邻接排列.

(2)解释各逻辑段空间关系的3个源文

a1.asm,声明1个组,4个段,涉及'匿名','dec_'类

(2.1)grp组,含seg1段
(2.2)seg1段
(2.3)ovlap段,用COMMON参与组合,'dec_'类
(2.4)touch段,用PUBLIC参与组合
(2.5)stk1段,用STACK指明栈段及PARA对齐

grpGROUPseg1

seg1SEGMENTPAGE
str1DB"S1$"
seg1ENDS

ovlapSEGMENTPARACOMMON'dec_'
str3DB'11$'
ovlapENDS

touchSEGMENTPUBLIC
ASSUMEcs:touch,ds:NOTHING

ORG11H

@:movah,9

movbx,grp;取grp段值
movds,bx

movdx,OFFSETstr1;取str1相对seg1偏置
int21h

EXTRNstr2:far

movdx,OFFSETgrp:str2;取str2相对grp偏置
int21h

ASSUMEds:ovlap

movbx,SEGstr3;取str3段值
movds,bx
leadx,str3;取str3相对ds偏置
int21h

touchENDS

stk1SEGMENTPAGESTACK
DW16HDUP(4AH);初值4AH的16H个字
stk1ENDS

END@

a2.asm,声明1个组,3个段,涉及'匿名','dec_','_stk'类:

财软联 盟 fs119.net



(2.6)ovlap段,用COMMON参与组合,'dec_'类
(2.7)stk2段,用STACK指明栈段及PARA对齐,'_stk'类
(2.8)grp组,含seg3段
(2.9)seg3段,'dec_'类

ovlapSEGMENTCOMMON'dec_'
DB'2'
ovlapENDS

stk2SEGMENTWORDSTACK'_stk'
DW13HDUP(2BH);初值2BH的13H个字
stk2ENDS

grpGROUPseg3

seg3SEGMENT'dec_'
PUBLICstr3
str3DB'33$'
seg3ENDS

END

a3.asm,声明1个组,4个段,涉及'匿名','_stk'类:

(2.10)grp组,含seg2段
(2.11)touch段,用PUBLIC参与组合
(2.12)seg2段
(2.13)stk2段,用STACK指明栈段及PARA对齐,'_stk'类
(2.14)seg1段

grpGROUPseg2

touchSEGMENTBYTEPUBLIC

EXTRNstr3:far
ASSUMEcs:touch,ds:NOTHING

@1:movcx,SEGgrp;取grp段值
movds,cx

movdx,OFFSETgrp:str3;取str3相对grp偏置
int21h

movcx,seg1;取seg1段值
movds,cx

movdx,OFFSETseg1:str4;取str4相对seg1偏置
int21h

movah,4ch;程序终止
int21h

touchENDS

seg2SEGMENTBYTE 财软联盟,fs119.net
PUBLICstr2
str2DB"S2$"
seg2ENDS

stk2SEGMENTWORDSTACK'_stk'
DW31HDUP(0B2H);初值B2H的31H个字
stk2ENDS

seg1SEGMENTBYTE
str4DB"%$"
seg1ENDS

END@1

用masm5.exe(版5.10B,囿95DDK),生成同名obj及lst文件.例如,汇编a1,命令行是:
masm5a1,,a1;

用含覆盖管理器的link4.exe(版5.01.17,同囿DDK),依序链接obj,生成a.exe程序文件,a.map映像文件,命令行是:link4a1a2a3,a,a,,,

a.exe,显'S1S22133%'

a.map含:

StartStopLengthNameClass
00000H00002H00003HSEG1
00010H00055H00046HTOUCH
00060H0008BH0002CHSTK1
0008CH0008EH00003HSEG2
0008FH00090H00002HSEG1
000A0H000A2H00003HOVLAPDEC_
000B0H000B2H00003HSEG3DEC_
000C0H00147H00088HSTK2_STK

OriginGroup
0000:0GRP

entrypointat0001:0011

(3)逻辑段排列准则:按链接次序,按字面段的源文次序,按类名大写ASCII次序

因此,a.exe含8个逻辑段(段名被大写):

(3.1)'匿名'类的a1的单逻辑段SEG1
(3.2)'匿名'类的a1与a3的组合逻辑段TOUCH,参与的a1及a3中touch字面段,代码相接. 财管家 园 fs119.net
(3.3)'匿名'类的a1的单逻辑段STK1
(3.4)'匿名'类的a3的单逻辑段SEG2
(3.5)'匿名'类的a3的单逻辑段SEG1
(3.6)'DEC_'类的a1与a2的组合逻辑段OVLAP,参与的a2及a3中ovlap字面段,使str3变为'21$'
(3.7)'DEC_'类的a2的单逻辑段SEG3
(3.8)'_STK'类的a2与a3的组合逻辑段STK2,参与的a2及a3中stk2字面段,按PUBLIC,两空间邻接

财软联 盟 fs119.net

财管 家园 fs119.net

财软联,盟,fs119.net


财软联盟.fs119.net

财软联.盟.fs119.net

(4)链接时,程序cs:ip及ss:sp设定

用'ENDexpression'形式指明的各伪指令,最先者,expression所在段,及expression相对所在段的偏置,是程序的cs:ip.无此伪指令,cs,ip是0.

例如,a1的'END@'先于a3的'END@1',因此,程序a.exe入口,cs=1,是@所在段相对exe文件装入模块首的节数,ip=11,是@相对所在段的偏置.

用组合属性STACK指明的各逻辑段,map文件最末者,是栈段;无此逻辑段,map文件最先逻辑段,是栈段.

例如,指明STACK的组合逻辑段STK2,后于单逻辑段STK1,因此,程序a.exe栈区,ss=STK2相对exe文件装入模块首的节数0ch,sp=88h,是STK2尺寸.

(5)汇编时的机器码暂定

能/不能被链接解决的作为操作数的段值/段偏置,其指令后面,带后缀R被暂定;能被链接解决的外部定义,其指令后面,带后缀E被暂定.因此,

a1.lst含:

0013BB----Rmovbx,grp
0018BA0000Rmovdx,OFFSETstr1
001DBA0000Emovdx,OFFSETgrp:str2
0022BB----Rmovbx,SEGstr3

财软.联盟.fs119.net

00278D160000Rleadx,str3

a3.lst含:

0000B9----R@1:movcx,SEGgrp
0005BA0000Emovdx,OFFSETgrp:str3
000AB9----Rmovcx,seg1
000FBA0000Rmovdx,OFFSETseg1:str4

(6)链接时的机器码暂定,及运行重定位exe文件

作为操作数的段值,相对装入模块首,被暂定.外壳command.com启动命令行上的程序时,先开辟被节号x,节长1的存储控制块(MCB)标识的空闲内存,此MCB前3个域值为:字节值5A(内存块链尾),字0(无效进程PSP),字y(x1y=A000段,即640K内存尾),然后在x1段首,先建10节程序段前缀(PSP),后铺展程序的装入模块.

这时,exe装入头的cs/ss值,与x11h(叫"装入段值")相加,形成运行cs/ss值,此为"运行重定位exe".装入模块中,链接时的各机器码暂定,与外壳指定的"重定位因子"相加,形成运行逻辑段值.

一般地,重定位因子=装入段值.也可用功能4b03的装入段值/重定位因子两参数,分别指定,如(8)所述.

因此,改a1.exe为a,做debuga,用U321,反出代码区:

财软,联盟,fs119.net



0321B409MOVAH,09
0323BB0000MOVBX,0000;取grp段值
03268EDBMOVDS,BX
0328BA0000MOVDX,0000;取str1相对seg1偏置
032BCD21INT21
032DBA8C00MOVDX,008C;取str2相对grp偏置
0330CD21INT21
0332BB0A00MOVBX,000A;取str3段值
03358EDBMOVDS,BX
03378D160000LEADX,[0000];ASSUMEds:ovlap时,取str3相对ds偏置
033BCD21INT21
033DB90000MOVCX,0000;取grp段值
03408ED9MOVDS,CX
0342BAB000MOVDX,00B0;取str3相对grp偏置
0345CD21INT21
0347B90800MOVCX,0008;取seg1段值
034A8ED9MOVDS,CX
034CBA0F00MOVDX,000F;取str4相对seg1偏置
034FCD21INT21
0351B44CMOVAH,4C
0353CD21INT21

(7)MS-DOS的exe文件两部构成:

前部,含装入头(1ch字节长)及重定位表;后部,是装入模块.

链接时的各机器码暂定,相对装入模块首的偏置:节,用2个字w_o,w_p,存于重定位表.

(7.1)装入头的字节偏置:

0,1:4d(M),5a(Z)标识
2,3:exe文件净长度,除以512后的余数
4,5:exe文件净长度,被512量的值
6,7:重定位表的项数 财软 联盟 fs119.net
8,9:前部占用节数
a,b:装入模块之后,所需最小节数
c,d:装入模块之后,所需最大节数
e,f:ss相对装入模块首的节数
10,11:sp
12,13:exe文件的字检查和
14,15:ip
16,17:cs相对装入模块首的节数
18,19:重定位表相对exe文件的字节偏置
1a,1b:覆盖号

a,长840字节(348h),做debuga,用D100L2e,显出exe文件头的前2Eh个字节:

01004D5A480102000400-20000000FFFF0C00
01108800D3A211000100-1E00000001001400
01200100230001002E00-010038000100

(7.2)解释装入头:

(7.2.1)a的长度,除以512后,余148H,放2,3字节
(7.2.2)a的长度,被512量,占2,放4,5字节
(7.2.3)重定位表,含4项
(7.2.4)exe文件前部,占20H节
(7.2.5)重定位表相对a,字节偏置是1eh

(7.3)相对a,字节偏置是1eh的重定位表解释:

第1项,w_o=14h,w_p=1,指出此机器码暂定,相对装入模块首,是1节14h偏置,即1*10h14h=24h(字节).

debug从100h装a,向高20h节(200h字节),是装入模块首,(100h200h)加上24h的324h处,恰为MOVBX,0000中的段值位置.
财管,家园,fs119.net


第2项,w_o=23,w_p=1,相对装入模块首,是1节23h偏置,即1*10h23h=33h(字节).300h加上33h的333h处,恰为MOVBX,000A中的段值位置.

同理,第3,4项,是MOVCX,0000及MOVCX,0008中的段值位置.

(8)重定位因子调度覆盖模块

功能4b03,铺展exe装入模块.前部略去PSP的装入模块,称覆盖模块.

调用覆盖模块cs:ip入口的常驻者(如ovlayer.exe),要做:

(8.1)将覆盖模块所在exe装入头中的程序cs:ip,读到entry
(8.2)调用功能4a,释放其尾后内存
(8.3)填写4b03的装入段值/重定位因子两参数
(8.4)调用功能4b03,它在空闲内存MCB之高1节,铺展覆盖模块
(8.5)用callentry语句,调用覆盖模块cs:ip入口

覆盖模块(如ovlayee.exe)工作完时,用retf,返回控制到常驻者.

覆盖模块被功能403铺展时,与(6)同样处理,作为movax,work操作数的段值work,与重
定位因子相加,这使ovlayee.exe,被ovlayer.exe调度,显示某区/某串值,例如,先显
o1区串s1值'os1',再显o2区串s2值'os2'. 财软联,盟,fs119.net

(8.6)ovlayee文
要点:只含1个逻辑段work,故work的机器码暂定,相对装入模块首,必为0,与重
定位因子的相加结果,恰=重定位因子.

要点:不需写"END@"伪指令,让cs/ip为0,而ss/sp,借用ovlayer.exe栈区.

worksegment
assumecs:work

pushds
movax,work
movds,ax

movah,9;显串
int21h;dx被ovlayer指定
popds

retf;远返回

workends
END

(8.7)ovlayer文
要点:引入PARA对齐的tail空段,使长度可变的ovlayer.exe,从PSP首到tail,作为新占用内存,tail之上,是空闲内存MCB.
要点:movbx,tail语句之后,勿写标号,否则masm5报错.

o1segment
s1db'os1$'
o1ends

o2segment
s2db'os2$'
o2ends

argsegment
loadsegdw2;装入段值
factordw2;重定位因子
entrydd4
filenamdb'ovlayee.exe',0
headerdb1chdup(1)
argends

stksegmentSTACK
dw16dup(9)
stkends

rootsegment
assumecs:root,ds:NOTHING

@:movax,arg
movds,ax
财.管家园.fs119.net
movax,3d00h;读打开
movdx,offsetarg:filenam
int21h
jnc@F;@F,@B,向前/后找最近的@@标号

movah,4ch
int21h

@@:movbx,ax;句柄送bx

movah,3fh;读装入头到header
movcx,1ch
movdx,offsetarg:header
int21h

movah,3eh;关闭
int21h

movbx,tail;tail指向映像尾节
movdi,es
subbx,di;bx是此程序新占用内存的节数

movah,4ah;新占用内存,始于es所指PSP节,长bx节
int21h

addbx,di
incbx

movds:loadseg,bx;装入段值=MCB之高1节

movax,segs1;重定位因子=s1所在段
movds:factor,ax

movax,wordptrds:[header14h];取覆盖模块ip
movwordptrds:[entry],ax

addbx,wordptrds:[header16h];覆盖模块的cs,加上MCB之高1节
movwordptrds:[entry2],bx

movax,ds
moves,ax

movax,4b03h
movbx,offsetarg:loadseg;es:bx指参数块
movdx,offsetarg:filenam;ds:dx指程序名
int21h

movdx,offseto1:s1;dx是s1相对o1的偏置
callds:entry

movax,segs2
movds:factor,ax;重定位因子=s2所在段 财管,家园,fs119.net

movax,4b03h
movbx,offsetarg:loadseg;es:bx指参数块
movdx,offsetarg:filenam;ds:dx指程序名
int21h

movdx,offseto2:s2;dx是s2相对o2的偏置
callds:entry

movah,4ch
int21h

rootends

tailsegment;空段
tailends

END@

财管家园,fs119.net

财管家,园,fs119.net

财管家园 fs119.net


财 软联盟 fs119.net

财软联 盟 fs119.net

(9)链接器3制静态覆盖块

link4的obj参数,囿于括号时,生成OVERLAY_DATA,OVERLAY_AREA,OVERLAY_END块,使DOS的exe长达16M.

用4个源文阐述:

(9.1)root文
要点:入口@需处于装入模块首
要点:extrn的near/far,声明近/远标号

c_rootsegment
assumecs:c_root

extrnov_near:near,ov_far:far,ov_far1:far

@:callov_near;近调用
callov_far;远调用
jmpov_far1;远转移
c_rootends

stksegmentSTACK
dw16dup(1)
stkends

END@

(9.2)ov_near文
要点:ret是近返回

c_nearsegment
assumecs:c_near

publicov_near

ov_near:movah,2
movdl,'N'
int21h

ret;近返回

c_nearends
END

(9.3)ov_far文
要点:retf是远返回

c_farsegment
assumecs:c_far

publicov_far

ov_far:movah,2
movdl,'F'
int21h
retf;远返回

c_farends
END

(9.4)ov_far1文:
c_far1segment
assumecs:c_far1

publicov_far1

ov_far1:movah,2 财管 家园 fs119.net
movdl,'f'
int21h

movah,4ch
int21h

c_far1ends
END

用masm5,生成扩展名为obj的root,ov_near,ov_far,ov_far1

用link4root(ov_nearov_far)(ov_far1),root3,3,,,
生成root3.exe,3.map

exe文件,未囿于括号的obj的各逻辑段,及不属于'CODE'类的代码,是常驻部分,计为0号覆盖块.括号组,生成1号,2号覆盖块.

root3.exe,显'NFf'

改root3.exe为root3,做debugroot3,用U300,反出代码区:

0300E82D00CALL0330
03039A40000000CALL0000:0040
0308EA50000000JMP0000:0050

3.map含:

StartStopLengthNameClass
Resident
00000H0000CH0000DHC_ROOT
00010H0002FH00020HSTK
00030H00036H00007HC_NEAR
00040H00046H00007HC_FAR
00050H00059H0000AHC_FAR1
00060H00082H00023HOVERLAY_DATADATA
00090H00090H00000HOVERLAY_AREACODE
00090H00090H00000HOVERLAY_ENDCODE
Overlay1H
Overlay2H

OriginGroup
0006:0DGROUP

改root3.exe为root3,做debugroot3,用D100L2A,显出exe文件头的前2Ah个字节:
财软联 盟 fs119.net
01004D5A830002000300-20000100FFFF0100
01102000795200000000-1E00000001000400
01200600060000000B00-0000

root3的重定位表,含3项:

第1项,w_o=4,w_p=6,指出OVERLAY_DATA块的字节偏置4,5
第2项,w_o=6,w_p=0,指出CALL0000:0040中的段值位置.
第3项,w_o=b,w_p=0,指出JMP0000:0050中的段值位置.

用D360L23,显出OVERLAY_DATA块:

03600100030000000000-0000000000000000
0370000000524F4F5433-2E45584500000000
038000003F

笔者探出,对OVERLAY_DATA块,字节偏置2,3,是覆盖块数3,偏置4,5,是cs相对装入模块首的节数.

(10)析栈初始

ML611,汇编map含

00000H,00000H_TEXTCODE
00000H,00019H_DATADATA
00020H,00020HSTACKSTACK
00040H,00033HTAIL

OriginGroup
0000:0DGROUP

entrypointat0004:0000

的t.asm

.modelsmall;仅数据段,代码段

.data;随psp

assumecs:@data

crydw'$!'

i72:pushax
pushdx
pushds

movah,9

movdx,cs
movds,dx

leadx,cry

财管家园.fs119.net

int21h

popds
popdx
popax
iret

i27dw0,@data

.stack32

tailsegment

.startup

movax,2572h
leadx,i72
int21h

movdx,256i27;计psp的驻容

movbyteptres:[1],27h;es矢psp

subi27[2],16;矢psp
calldwordptri27;转psp:0

tailends
end

lst含

00150000----Ri27dw0,@data

0000tailsegment

.startup

0017movax,2572h
002Fcalldwordptri27

exe文件头

01004D5A730002000200-20000000FFFF0200
01102000000000000400-1E00000001001700
0120000001000400

重定位表,第1项,矢i27的@data,第2项,矢17字节长的.startup第1字节

00BA0000MOVDX,0000;运行时,字节1,2,加mcb所占节号及11h,制DS
038EDAMOVDS,DX
058CD3MOVBX,SS;外壳,已加好mcb所占节号及13h到SS
072BDASUBBX,DX;13h-11h,差值2节,合20h字节
09D1E3SHLBX,1
0BD1E3SHLBX,1
0DD1E3SHLBX,1
0FD1E3SHLBX,1
11FACLI;防来中断128ED2MOVSS,DX;
1403E3ADDSP,BX;本模式,移栈段环境到数据段高端
财软联 盟 fs119.net

16FBSTI

(10.1)DEBUGt.exe实例

栈初始前,DS矢psp,SS已加好,SP=exe头偏移10,11字节值20h:

AX=0000BX=0000CX=0073DX=0000SP=0020BP=0000SI=0000DI=0000
DS=188BES=188BSS=189DCS=189FIP=0000

初始后,DS,SS矢@data,SP多加栈容20h字节:

AX=0000BX=0020CX=0073DX=189BSP=0040BP=0000SI=0000DI=0000
DS=189BES=188BSS=189BCS=189FIP=0017
财管家园 fs119.net

财软联 盟 fs119.net

财软联盟.fs119.net


文章摘自网络,如有侵权,请与我们联系.
数据统计中!!
上一篇:动态库的执行时间
下一篇:仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现

精品课程推荐



用户名: 密码: 匿名? 注册