<STRONG>
/ C# g7 d# a; z< ><STRONG>重要声明:本文乃转载自其他社区,由于在下无法获得任何有关作者和出处的信息,所以不能在此登出,恳请作者原谅,并希望知情者能告知在下。本着资源的共享的精神,在下深信作者不会拒绝在下的转载行为。同时强烈BS数学中国的下载系统,它不但不能及时给予他人需要的帮助,还浪费了他人大量的时间,仅仅是为了获得无聊的点数,而且遗憾的是,那些点数并不能保证你真能获得帮助!</STRONG></P>
. h0 j8 l2 [9 n y3 F( b< ></STRONG><STRONG>符号表<br></STRONG> 符号表是对象文件中用来保存符号信息的一张表,也是COFF文件中最为复杂的一张表。所有段落使用到的符号都在这个表里。它也是由很多条记录组成,每条记录都以如下结构保存:<br>typedef struct {<br> union {<br> char cName[8]; // 符号名称<br> struct {<br> unsigned long ulZero; // 字符串表标识<br> unsigned long ulOffset; // 字符串偏移<br> } e;<br> } e;<br> unsigned long ulValue; // 符号值<br> short iSection; // 符号所在段<br> unsigned short usType; // 符号类型<br> unsigned char usClass; // 符号存储类型<br> unsigned char usNumAux; // 符号附加记录数<br>} SYMENT;<br> cName符号名称,和前面所有的名称一样,它也是8个字节,但不同的是它在一个联合体中。和它占相同的存储空间的还有ulZero和ulOffset这两个成员。如果符号的名称只有8个字符,那很好,可以直接放到这个cName中;可是,如果名称的长度大于8个字节,这里就放不下了,只好放到字符串表中。这时候,ulZero的值就会为0,而在ulOffset中会给出我们所用的符号的名称在字符串表中的偏移。<br> 一个符号有了名称不够,它还要有值!ulValue就是这个符号所代表的值。<br> iSection成员指出了这个符号所在的段落。如果它的值为0,那么这个符号就是一个外部符号,要从其它的COFF文件中解析(连接多个目标文件就是要解析这种符号)。当它的值为-1时,说明这个符号的值是一个常量,不是它在段落中的偏移。而当它的值为-2时,这个符号只是一个调试符号,只有在调试时才会用到它。当它大于0时,才是符号所在段的索引值。<br> usType是符号的类型标识。它用来说明这个符号的类型,是函数?整型?还是其它什么。这个标识是两个字节。<br> 低字节的低四位是基本标识,它指出了符号的基本类型,如整型,字符,结构,联合等。高四位指出了符号的高级类型,如指针(0001b),函数(0010b),数组(0011b),无类型(0000b)等。现在的编译器,通常不使用基本类型,只使用高级类型。所以,符号的基本类型通常被设为0。<br>高字节通常未用。<br> usClass是符号的存储类型标识。它指明了符号的存储方式。<br> 其值与意义见下表:<br></P>( W( ]: B$ A" V1 n- k: d% l
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="80%" align=center bgColor=#ffffff borderColorLight=#000000 border=1>
- G' W4 N! I: k# `
' i9 }/ R- X i9 R: M! z8 E<TR>+ N, P. @* h3 W, X* n4 p
<TD vAlign=top width=55>值</TD>8 Q* q$ _; ] o5 W" p3 r5 x
<TD vAlign=top width=72>名称 </TD>* D7 J" J5 y. P5 q8 i
<TD vAlign=top width=441>说明</TD></TR>
) r7 [* t" e. R0 `" i( |<TR>
& N# J5 Y, b% w2 T& r0 y<TD vAlign=top width=55>NULL</TD>
) ]5 g8 ^2 P# H% f<TD vAlign=top width=72>0</TD>- F( A; {: d3 F
<TD vAlign=top width=441>无存储类型。</TD></TR>: x% A; n, o5 B; F" M' f6 J& t
<TR>
W8 W' a5 i, P: v3 A1 k0 o<TD vAlign=top width=55>AUTOMATIC</TD>! u0 f0 p+ {4 U: T$ W# h
<TD vAlign=top width=72>1</TD>4 I1 n2 X* M$ D8 p) r' t
<TD vAlign=top width=441>自动类型。通常是在栈中分配的变量。</TD></TR>- s- ^; r9 M; T4 d
<TR>
. K/ k0 k0 q) Q* M( @! z! F1 E<TD vAlign=top width=55>EXTERNAL</TD># c5 |% L/ e2 x8 |1 k$ ~7 S
<TD vAlign=top width=72>2</TD>
+ n2 v2 R) d4 m3 H1 C<TD vAlign=top width=441>外部符号。当为外部符号时,iSection的值应该为0,如果不为0,则ulValue为符号在段中的偏移。</TD></TR>
( `# q" A' A+ J, @6 \4 U<TR>
" G/ N5 O, j2 z* O<TD vAlign=top width=55>STATIC</TD>- D; t% V" d5 v( m2 L* Q2 A
<TD vAlign=top width=72>3</TD>+ b4 s3 ] j, c$ y0 ?
<TD vAlign=top width=441>静态类型。ulValue为符号在段中的偏移。如果偏移为0,那么这个符号代表段名。</TD></TR>/ L" I3 K+ b- E8 d! |$ p% p2 M
<TR>2 _+ Z. q' {+ c9 b: W3 {3 M! }
<TD vAlign=top width=55>REGISTER</TD>
- B" n0 F V3 g<TD vAlign=top width=72>4</TD>/ |. {( m% v" ?
<TD vAlign=top width=441>寄存器变量。</TD></TR>
: w1 H6 [3 M0 }& i' C9 X* u<TR>
: a4 y8 a5 K; l" r2 p3 l<TD vAlign=top width=55>MEMBER_OF_STRUCT</TD>- d' Y& U5 E0 q$ W' {. P
<TD vAlign=top width=72>8</TD>
' J4 x0 Z, k6 ?% K* m6 g* y% E& C& m<TD vAlign=top width=441>结构成员。ulValue值为该符号在结构中的顺序。</TD></TR>
" R% X* X1 c' h9 k4 v; F" U<TR>' H/ A3 Z; q# k2 b' P" _
<TD vAlign=top width=55>STRUCT_TAG</TD>8 N9 F V! R. c2 q* P$ J
<TD vAlign=top width=72>10</TD>
4 ]0 N0 ?* l& ~- Y w/ T<TD vAlign=top width=441>结构标识符。</TD></TR># E3 `% r% ?( T: J& s; a2 o
<TR>
) f& W* x1 q+ K3 x<TD vAlign=top width=55>MEMBER_OF_UNION</TD>7 m# A! C- n* Y) ~$ ?
<TD vAlign=top width=72>11</TD>
[, @, g: `1 P7 |* o8 O<TD vAlign=top width=441>联合成员。ulValue值为该符号在联合中的顺序。</TD></TR> }* {( X) P! O9 ?/ ?2 {
<TR>
+ S9 V/ X% Z) a. E6 x<TD vAlign=top width=55>UNION_TAG</TD>8 F2 i& R( z+ m1 `
<TD vAlign=top width=72>12</TD>$ U, J4 `% Y8 K) F. s
<TD vAlign=top width=441>联合标识符。</TD></TR>7 n2 {# x. b+ C; h- I
<TR>& T$ y# q7 x( E
<TD vAlign=top width=55>TYPE_DEFINITION</TD>5 ?8 F: P$ C2 U% B$ H
<TD vAlign=top width=72>13</TD>
: m* h, e$ {7 Q& G' B2 W<TD vAlign=top width=441>类型定义。</TD></TR>! v+ m. T& B% V5 ~3 F
<TR>
' {' U: \$ g; X. C& j5 \: ]<TD vAlign=top width=55>FUNCTION</TD>
/ r) Y6 M3 b5 l; `0 q<TD vAlign=top width=72>101</TD>
( [' n( r5 _2 |% Y! T$ v<TD vAlign=top width=441>函数名。</TD></TR>
; S4 j3 M$ \7 M" J0 s0 Q<TR>
3 o, h# {, _3 l l<TD vAlign=top width=55>FILE</TD>5 U' x: f% O# s* V
<TD vAlign=top width=72>102</TD>
* c6 U; {4 @1 W<TD vAlign=top width=441>文件名。</TD></TR></TABLE>
1 z$ J8 E' ]( j/ {3 d# m) o4 R<DIV> 最后一个成员usNumAux是附加记录的数量。附加记录是用来描述符号的一些附加信息,为了便于保存,这些附加记录通常选择成为一条符号信息记录的整数倍(多数为1)。所以,如果这个成员的值为1,那么就表示在当前符号信息记录后附加了一条记录,用来保存附加信息。<br> 附加信息的结构是与符号的类型以及存储类型相关的。不同的类型的符号,其附加信息(如果有的话)的结构也不同。如果你不在意这些内容,也可以把它们乎略。<br> 当段的类型为FILE时,附加信息就是一个字符串,它是目标文件对应源文件的名称。其它类型在介绍PE时再进行详细讨论。</DIV>
/ H& K' L! X1 G Y9 \4 C[此贴子已经被作者于2005-9-17 14:53:44编辑过] |