📄 tsm_util.txt
字号:
east=254,
south,
west,
pad$0=256}
color ENUM {
red,
green=256,
blue}
Processing Simple Aggregate Declarations
----------------------------------------
Structures and unions are mapped by H2ASH onto their direct TASM STRUC
and UNION counterparts. If a tag is not present in the aggregate declaration,
H2ASH automatically generates one. The GLOBAL directive is used to represent
an instance of the structure, where the type-field contains that tag name of
the structure or union in question. For example,
---- H2ASH input ----
struct S1 {
int field1;
int field2;
} S1_object;
union U1 {
int field1;
int field2;
int (*field3)(void);
} U1_object;
---- H2ASH output ----
S1 STRUC
@S1@field1 DW ?
@S1@field2 DW ?
S1 ENDS
GLOBAL C S1_object :S1
U1 UNION
@U1@field1 DW ?
@U1@field2 DW ?
@U1@field3 DW NEAR PTR ?
U1 ENDS
GLOBAL C U1_object :U1
Using the word-alignment (-a) option lets H2ASH explicitly output
appropriate padding. For the exact structure-alignment rules, see the
C++ Programmer's Guide. For example,
---- H2ASH input ----
struct S2 {
char field1;
int field2;
};
---- H2ASH output ----
S2 STRUC
@S2@field1 DB ?
DB 0
@S2@field2 DW ?
S2 ENDS
H2ASH treats nested structures as separate TASM STRUC declarations, and
gives the nested structures specially mangled names. This is done because
nested structures are not true members; they are merely in the lexical scope
of the structure in which they are contained. However, if a nested structure
is instantiated (for example, an object of the type of that structure is
declared), the appropriate space is reserved in the enclosing structure as
in the following example:
---- H2ASH input ----
struct a {
int i;
struct b {
int j;
};
int k;
struct c {
int l;
} c_instance;
};
---- H2ASH output ----
@a@b STRUC
@a@b@j DW ?
@a@b ENDS
@a@c STRUC
@a@c@l DW ?
@a@c ENDS
a STRUC
@a@i DW ?
@a@k DW ?
@a@c_instance @a@c <>
a ENDS
Processing Bitfield Declarations
--------------------------------
Bitfields are represented by H2ASH as TASM RECORD declarations. In
general, it generates two kinds of RECORDS. First, if a STRUCT contains
only bitfield declarations and if each of the bitfields are of the same type,
and if this type is sufficiently large to contain all of the fields, H2ASH
generates a global RECORD declaration. H2ASH inserts a uniquely named padding
field at the top of the RECORD so that proper alignment is achieved. For
example,
---- H2ASH input ----
struct S1 {
int field1: 1;
int field2: 4;
};
---- H2ASH output ----
S1 RECORD {
pad$0 :11
field2 :4
field1 :1
}
If H2ASH is unable to generate a global RECORD declaration, a local one
is emitted within the STRUC in which the original bitfield is declared.
Furthermore, a member with the type of the tag of the local RECORD
declaration is declared to reserve the appropriate amount of storage. H2ASH
attempts to pack adjacent bitfields within a single record when adjacent
bitfields are of the same type, and whenever the type of the bitfield is
large enough to contain the adjacent fields. For example,
---- H2ASH input ----
struct S1 {
int field1;
char field2: 1;
char field3: 8; // NOTE: cannot be packed with field2
};
---- H2ASH output ----
S1 STRUC
@S1@field1 DW ?
S1 RECORD {
pad$0 :7
field2 :1
}
$bit$0 S1 <>
S1 RECORD {
field3 :8
}
$bit$1 S1 <>
S1 ENDS
Processing Function/Operator Declarations
-----------------------------------------
File scope function declarations are emitted as GLOBAL declarations with
type NEAR or FAR, depending on the model settings. Prototypes for func-
tions are ignored, because TASM does not support typed CALLs or typed PROTO
statements. However, the prototype is encrypted by the mangled name of the
function. For example,
---- H2ASH input ----
void fvv(void);
extern efvv(void);
int fiii(int, int);
---- H2ASH output ----
GLOBAL C @fvv$qv :NEAR ;or far, depending on model
GLOBAL C @efvv$qv :NEAR ;or far, depending on model
GLOBAL C @fiii$qii :NEAR ;or far, depending on model
H2ASH ignores default arguments, as well as all function bodies. In both
cases, H2ASH issues a warning and processes that declaration as if the
default arguments and function bodies were not present. H2ASH also ignores
static function declarations. In this case, the declaration is not emitted
into the output stream. Here's an example:
---- H2ASH input ----
static sfvv(void);
void dfii(int i = 0, int = sizeof(foo));
int fvv(int i) { return ++i; }
---- H2ASH output ----
; warning, declaration of static function 'sfvv(...)' ignored
void C @dfii$qii :NEAR ; warning, default arguments ignored
void C @fvv$qi :NEAR ; warning, function body ignored
H2ASH supports function and operator overloading by encoding function
prototypes and operator names. Otherwise, H2ASH treats these declarations
in exactly the same manner as ordinary functions. For example,
---- H2ASH input ----
int abs(int, int);
int abs(int);
struct alpha;
int operator+(alpha, int);
int operator+(int, alpha);
---- H2ASH output ----
GLOBAL C @abs$qii :NEAR
GLOBAL C @abs$qi :NEAR
GLOBAL C @$badd$q5alphai :NEAR
GLOBAL C @$badd$qi5alpha :NEAR
Processing Classes
------------------
C++ classes are mapped onto TASM STRUC declarations, just as C STRUCTS
are. Nonstatic class data members are treated as ordinary STRUCT fields.
Static class data members are treated as GLOBAL declarations, and are emitted
after the class declaration in which they are declared. Nonvirtual function
members are treated exactly like ordinary function definitions, except, that
they receive a mangled name that encodes the tagname of class in which they
are contained. Virtual function members are treated exactly like nonvirtual
functions, except that they force H2ASH to allocate space for a virtual-
function-table-pointer. This pointer has a mangled name containing the
suffix 'vptr$', which is always unique throughout a single compilation unit.
Finally, all 'special' member functions (constructors, copy constructors,
assignment operators), are treated as ordinary function declarations.
However, if they are compiler-synthesized members, H2ASH does not emit them.
For example,
---- H2ASH input ----
class c {
static int static_member;
int normal_member;
public:
virtual void f1_virtual(void);
virtual void f2_virtual(void);
void f3_normal(void);
void *operator ++();
c();
c(int&);
~c();
};
---- H2ASH output ----
c STRUC
@c@vptr$0 DW NEAR PTR ?
@c@normal_member DW ?
c ENDS
GLOBAL C @c@static_member :WORD
GLOBAL C @c@f1_virtual$qv :NEAR
GLOBAL C @c@f2_virtual$qv :NEAR
GLOBAL C @c@f3_normal$qv :NEAR
GLOBAL C @c@$binc$qv :NEAR
GLOBAL C @c@$bctr$qv :NEAR
GLOBAL C @c@$bctr$qri :NEAR
GLOBAL C @c@$bdtr$qv :NEAR
H2ASH supports single inheritance. If a program using multiple inheri-
tance is presented as input, or if virtual bases are present, H2ASH
terminates and gives an appropriate error message. Within a derived class, a
base class is represented as a member subobject, and is treated by H2ASH as
if it were an ordinary member with a specially synthesized name: 'subobject$'
which has the type of the base class in question. Again, this name is always
unique. Virtual function table pointers are shared between the base and
derived class; hence, no further space is allocated for the virtual-pointer
within the derived class. For example, adding a derived class to the
previous example:
---- H2ASH input ----
// previous definition for class c goes here.
class d : c {
int derived_member;
virtual void f1_virtual(void); // virtual override of c::f1_virtual()
d();
~d();
};
---- H2ASH output ----
d STRUC
subobject$0 c <>
@d@derived_member DW ?
d ENDS
GLOBAL C @d@f1_virtual$qv :NEAR
GLOBAL C @d@$bctr$qv :NEAR
GLOBAL C @d@$bdtr$qv :NEAR
Pointers to class members are also supported, both pointers to data
members and pointers to function members. Here's a simple example:
---- H2ASH input ----
class f{
public:
int x;
int * px;
int foo( char * ) { return px }
};
int f::*pointer_to_data_member;
int (f::*pointer_to_function)(char *);
---- H2ASH output ----
f STRUC
@f@x DW ?
@f@px DW NEAR PTR ?
f ENDS
GLOBAL C @f@foo$qpzc :NEAR
vb_data$mptr STRUC
vb_data$member_offset DW 0
vb_data$vbcptr_offset DW 0
vb_data$mptr ENDS
GLOBAL C pointer_to_data_member :vb_data$mptr
vb_near_func$mptr STRUC
vb_near_func$func_addr DW 0
vb_near_func$member_offset DW 0
vb_near_func$vbcptr_offset DW 0
vb_near_func$mptr ENDS
GLOBAL C pointer_to_function :vb_near_func$mptr
C++ Templates are not supported in this version of H2ASH. If a program
containing templates is given as input, H2ASH outputs an error and terminates
execution.
/**************************** END OF FILE ********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -