Details of some changes in C --.

List of the references on the version of the compiler.

0.238 from 28.03.2002
0.237 from 05.11.2001
0.236 from 13.02.2001
0.235 from 13.11.2000
0.234 from 01.10.2000
0.233 from 11.09.2000
0.232 from 31.08.2000
0.231 from 16.07.2000
0.230 from 13.06.2000
0.229 from 06.04.2000
0.228 from 08.03.2000
0.227 from 09.02.2000
0.226 from 10.01.2000
0.224 from 28.10.1999
0.223 from 05.10.1999
0.222 from 19.09.1999
0.221 from 10.09.1999
0.220 from 23.08.1999
0.219 from 06.07.1999
0.218 from 14.06.1999
0.217 from 24.05.1999
0.216 from 21.04.1999
0.215 from 14.03.1999
0.214 from 18.02.1999
0.213 from 01.02.1999
0.212 from 07.12.1998
0.211 from 15.11.1998
0.210 from 15.10.1998
0.209 from 24.09.1998
0.208 from 06.09.1998
0.207a from 6.08.1998
0.206 from 05.06.1998


0.238 from 28.03.2002



Compilation of resources.
~~~~~~~~~~~~~~~~~~~~~~~~~~
    Built-in in C-- the compiler of resources on the possibilities concedes
to specialized compilers of resources, but these possibilities, as it seems,
will be enough for majority of your problems.

    It will be easier to list that built-in in C-- the compiler of resources
does not know how to make.  The operators of resources are not treated:
'VERSION', 'VERSIONINFO' and difiniendums by the user resources.  If
necessary, it is possible to enter datas entered with the help of of these
operators, with the help of of operator 'RCDATA'.  Many operators of
resources have optional parameters 'loading' and 'memory'.  The support of
these parameters is not realized.  By meeting these parameters, the compiler
simply will pass them.

    To include the C-- compiler to treat resources it is possible by two
methods:

    1. To include in the project by the instruction '#include' the file with
the '.rc' extension.  Files with such extension the compiler considers as the
file with resources. The file of resources is necessary for including in your
project only after inclusion of heading files Windows.

    2. Resources it is possible to possess in a skew field of the program in
any place, but the text of resources should begin with the instruction
'#pragma resource start', and to be finished by the instruction '#pragma
resoutce end'.  The resources can be divided on a part and these parts it
possible to possess in any place, convenient for you, (silly to possess
resources in the block of the comments and then to be surprised, why they
were not compiled).  The compiler will collect these parts and will compile.

    It is possible to write names of operators both large, and small letters,
but the names of identifiers are sensitive to the register.  In the text of
resources it is possible to use the directives and comments.


Outside labels (out of procedures)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The outside labels are placed in the program's data area. If the data and
code are situated in the only segment (that's the usual way for c-- to place
them together) the outside labels become a simple and effective way for
getting the addresses of different program parts.

    Unique identificators may be used for naming the labels. You can use
capital, small and the mixture of them while giving the label a name.


Advanced features of pointers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Since now you can use pointer-typed variables to pass to procedure with
the other parameters. You can use pointers as procedure's local variables
too.  You can also use pointers in structures. The pointers to pointers are
also available. Procedure-pointers support is added too:

void (*proc)();  // procedure-pointer declaration

    By default the pointers on a procedure are the pointers on a procedure in
style 'pascal', irrespective of the register, in which the name of a
procedure and mode of compilation is written.  If it is necessary, that other
type of call was used, it is necessary for indicating for want of declaration
of the pointer a procedure.

    The compiler does not control the contents of the pointer while
initializing it. That is you can make 'char' pointer to be pointed to 'int'
pointer or to make a procedure-pointer to be pointed to a variable, i.e.
there's no type-verify. That's there may be a mistake in the program
concerned with the type confusion.


Declaring procedures in structures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    With the introduction the support for the procedures in structures,
structure becomes a similar to C++ class. That is such procedure becomes a
class-member. Example:

struct Point  // class declaration
{
    int x; // data members of
    int y; //  the Point class
    void SetX(int);  // methods declaration
    void SetY(int);  // belonging to the Point class
};

void Point::SetX(int _x)  //Point class function declaration
{
    IF((_x>=0)&&(_x<=MAX_X)) x=_x;
// x,y variables are the member of the class that is why the access to them
// from the procedures of the class is indirect.
 }

void main()
Point p;  //declaring a structure in stack
{
  p.y = p.x = 0;
  p.SetX(1);
}

    When a class member (procedure) is called  the address of the class
(structure) is implicitly passed to it. In the procedure the address is
accessible via the name of a parametric variable 'this'. This variable is
automatically generated by the compiler. If a procedure (class member) is
defined as 'static' the address of the class is not passed to the procedure
and 'this' variable is not generated for it.

    The procedure declared in a structure can be a dynamic one. For this
purpose a ':' (colon) symbol must be placed before the name of the procedure
in the declaration. But such a procedure cannot be used as a macros.


Inheriting
~~~~~~~~~~
    The C-- supports both simple and multiple inheritings. The declaration of
an inherited structure looks like the following:

struct Derived : Base1, Base2, ... Basen
{
  int x0;
};

    The number of base structures is not restricted. In case of multiple
inheritance a structure can inherit two or more copies of the base structure.
But in this case ambiguity takes place. Example:

struct A
{
  int x0,y;
  . . .
};

struct B : A  //structure 'B' inherits 'A'
{
  . . .

};

struct C : A  //structure 'C' inherits 'A'
{
  . . .
};

struct D : B, C //structure 'D' inherits 'B' and 'C'
{
  . . .
};

void main()
D d;  // allocating a memory block for the 'D' structure in stack and assigning
//a name of 'd' to it
{
  d.x0=0;

    In this example the 'D' structure inherits two copies of the 'A'
structure and the first one contains two elements called 'x0'. The C++
compilers show an error message compiling the string 'd.x0=0'. By default the
C-- treats that record and makes the element of the last inherited structure
to get the value. To get access to the first inherited 'x0' element the '::'
operator must be used:

  d.B::x0=0;

    That is, the records:

  d.x0=0;

    and

  d.C::x0=0;

    are equal.


Passing parameters to stack procedures via registers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The most compact and the fastest code is made when parameters are passed
via registers. But the contents of the registers can be easyly destroyed. If
a parameter is used once to initialize a register you can pass the value into
the procedure at once via register, by-passing the stage of pushing and
popping the contents with the stack. Example:

int proc (int param1, param2, param3)
{
  (e)BX = param3;
  (e)BX.TAG_STRUCT.var = proc2 (param1,papra2);
  proc3 (param1,param2);
}

    In the example the param3 parameter is only used to initialize (e)BX
register that is why it can be passed via register:

int proc (int param1, param2, (e)BX)
{
  (e)BX.TEG_STRUCT.var = proc2 (param1,papra2);
  proc3 (param1,param2);
}

    As you see, the procedure has become slightly simpler.

    It is neccessory to remember that the contents of registers can be simply
damaged therefore the best thing to do about parameters is to use register
parameters after pushing the stack ones. For 'pascal' procedures register
parameters is better to place after stack ones. For 'cdecl' and 'stdcall'
procedures is better to place register parameters maiden.


Assigning the same value to several variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If you need to assign the same value to several variables:

  var1=0;
  var2=0;
  var3=0;

    now you can write the same more briefly:

  var1=var2=var3=0;

    The more compact and faster code is generated while using this way.


'static' keyword and '::' operator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If you specify 'static' keyword before the declaration of a global
variable, a structure or a procedure they will be available only in the file
they are declared in. That means if you include this file with 'include'
directive into another one the variables declared as 'static' will not be
available in the main file and you can declare the variables with the same
names in the main file.

    If a local variable defined in a procedure as 'static' the memory for it
will be allocated not in the stack but in the data area. But the variable
will be available only inside the procedure where it was declared. Making a
local variable to be 'static' gives an opportunity to save the value of the
variable for the next entrance into the procedure.

    Any global object (a variable, a structure or a procedure) can be
declared as 'static'. For the local usage the keyword can be applied only to
variables.

    If there was a global and a local variable with the same name in the
program you had no access to the global one. Now you can get access to the
global variable using '::' operator. Example:

int var;  //declaring a global variable

void proc()
int var;  //declaring a local variable with the name of
         // the existing global variable
{
  (e)AX=var;    //accessing the local variable
  (e)AX=::var;  //accessing the global one
}


Replacement of 'return' with 'goto'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In some situations (when compiling a program) 'return' operator will be
replaced with 'goto'. It takes place when code size optimization is enabled
and appliable for 'return' operators which are situated inside the procedure
and the code size for using 'return' is bigger than for 'goto'. This method
is always used for dynamic procedures used as macros. The 'goto' operator
will be executed only in the end of the procedure. If a dynamic procedure is
used as a macros the 'return' operator situated in the end of the procedure
will be by-passed by the compiler.

    Thus, the last limitation for using dynamic procedures as macros is
removed. Now any dynamic procedure can be used as a macros.

    For the 'goto' operator there is a shorter clone - 'GOTO'. For obtaining
more compact code for the 'return' operator a shorter 'RETURN' operator is
introduced too. It can be used if between the place where it is used and the
end of the procedure there is no more than 128 bytes. In the another case the
compiler will display an error message. When using 'return' in the smaller
than 128 bytes distance to the end the compiler will display a warning
message because it is possible to use the 'RETURN' operator.


Bit fields of structures
~~~~~~~~~~~~~~~~~~~~~~~~
    Bit fields are used for memory saving because they let to pack values
densely, they are also used for convenient access to the registers of the
peripherals in which several bits may have independent functional assignment.

    The declaration of a bit field has the following syntax:

 []:;

Example:

int var:5; //declaring a bit field by the size of 5 bits named as 'var'


    A bit field consists of a number of bits which is specified by a
numerical . Its value must be a positive integer and it must be
below or equal the number of bits in the . In C-- bit fields can
contain only unsigned values. The arrays of bit field and the pointers to
them cannot be used.

    The  names a bit field. Its presence is not necessary.
Unnamed bit field means a skip of bits before the next structure member. The
unnamed zero-sized bit field has a special assignment: it guarantees that the
memory for the next bit field will be started on the boundary of the type
specified for the unnamed bit field. That is the bitfield will be aligned on
8/16/32 bits.

    In C-- all the bit fields are packed one after another irrespective of
the boundaries of the identifiers' types. If the next field is not a bit
field the rest bits before the boundary will not be used. The maximum size of
a bit field is 32 bits for 'dword/long' type, 16 bits for 'word/int' type and
8 bits for 'byte/char' type. Bit fields can be united, i.e be used with the
'union' operator. The 'sizeof' operator for the bit field will return the
size of the field in bits. When using a bit field, its contents will be
extended into a register as an unsigned integer.


   === === ===
* README.TXT - ENGLISH - SPHINX C-- v0.238 beta 4 *
(C) 2002 Written by Michael Sheker
(C) 2002 Translated from Russian by YBX (exhu@tut.by), FIDONET: 2:454/21.43
PLEASE, SEND ANY COMMENTS, CORRECTIONS, NOTES etc. !!!
Return to list version.


0.237 from 05.11.2001



Use of dynamic procedures by way macro.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Now any dynamic procedure can be used as ¬ ªàro.  If before call of a
dynamic procedure to deliver a numeral '@', the code of this procedure will
be inserted, instead of is called by the instruction CALL.

    In dynamic procedures, which will be used by way macro, on former it is
impossible to use an operator 'return'.

    For want of use of push-down dynamic procedures by way macro the clearing
of the stack of transferred parameters is made by the assembly instruction
'ADD SP,SIZE_PARAMETRS' at once after termination a code inserted macro.  On
this, if this procedure used flags as return, they will be desroyed.



The new assembly instructions.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In the compiler the support 19 new instructions MMX of the extension and
46 instructions SSE of the extension is added.  Many from these instructions
can use as an operand 64-bit and 128-bit cells of memory.  The C-- compiler
now can work only with 32-bit variables.  Therefore for the instructions of a
cell, using as an operand, of memory by a size more than 32-bit is possible
to use variables of any types.  The compiler will not issue on it the
messages on an error, the address of this variable will be used, and
instruction will use the number, necessary to it, of bits of memory, since
addresses of the indicated variable.  For example:

For the instruction "movaps" one from operands can be a 128-bit cell of
memory. For this instruction are allowed the following syntax:

byte var8_128 [16];
word var16_128 [8];
dword var32_128 [4];

void proc ()
{
asm {
  Movaps var8_128,xmm0 //in an array from 16 bytes will be noted contents XMM0
  Movaps xmm1,var16_128 //in XMM1 will be noted contents 8 words
  Movaps var32_128,xmm1 //in an array from 4 double words will be noted XMM1
}
}



Automatic choice of word length of the registers.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For want of creation of library procedures very much frequently it is
necessary to write variants of a procedure for work in 16-bit and 32-bit
modes, which differ from each other only by use in them either 16-bit or
32-bit registers accordingly.  Now it is possible to write only one
procedure, using in to it new syntax of the registers. If the compiler will
meet here such syntax:

  (E)AX = 0;

    That the compiler will use for want of compilations of a 16-bit code the
register AX, and for want of compilations of a 32-bit code the register EAX.

    The use of the automatic registers will allow to simplify library files
and to make by their more clear.


Ranges of significances for an operator case/CASE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For an operator case/CASE, which can be used only in a skew field of the
block of an operator switch/SWITCH, the range of significances is possible to
specify. At first it is necessary to specify smaller significance, then
after dots greater. An example:

switch (AX) {
  case 1... 5:
    WRITESTR ("Range AX from 1 to 5");
    BREAK;
};

    Earlier you had to write a more bulky construction:

switch (AX) {
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    WRITESTR (" Range AX from 1 to 5 ");
    BREAK;
};

    Besides that the new format of an entry is more compact and more read,
but still for want of it the compiler creates a more compact and fast code.


Preservation of address of a variable environment.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    If for want of compilations of the program you in the command line will
add an option -ENV or in the c--.ini file a line ENV, the compiler will add
in your program a variable 'environ', in which for want of to loading will be
saved address of a variable environment of the started program. For the
programs under Windows it will be full address, and for remaining in this
variable the address of segment will be saved only.


Return of flags from procedures.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Many of DOS the functions 0x21 of interruption as the indicator of
successful fulfilment use installation or dumping carry flag. To use flags of
the processor for want of return from procedures it is possible and in other
cases, when it is necessary to have the status of successful or not
successful fulfilment of a procedure. It will allow more completely to use
possibilities of the processor and accordingly will reduce a size of a code
and will increase speed of the program.

    Alongside with flags, for want of return from procedures, on former there
is a return of various types and through the register AL/AX/EAX. If for a
procedure is declared, that it has a type of return int and CARRYFLAG, for
want of use of such procedure in operations of a comparison IF, WHILE...  The
check carry of a flag, instead of comparison of the register AX will be done.
Example of use of return of flags from procedures:

int CARRYFLAG FOPEN (); 	 // the declaration of a procedure

void proc ()
{
  IF (FOPEN (name, 0)) Error (" Not open file ");
}

    Variants of allowable syntax for use of return of a flag:

IF (! FOPEN ())...
IF (FOPEN ())...
IF (! FOPEN ())...
IF (handl = FOPEN ())...
IF (handl = FOPEN ())...
IF (! Handl = FOPEN ())...
IF (! Handl = FOPEN ())...

    And here variants, in which, in spite of the fact that for a procedure
the return of a flag is declared, the comparison of the register AX will be
made:

IF (FOPEN () == 5)...  // the comparison is made
IF (FOPEN () + 2)...   // the outcome of a procedure is subjected further
                       // to calculation, in which outcome the flags will be
		       // are changed.


LE a format of exe-files for DOS32.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For want of use LE of a format of exe-files under DOS32, on a comparison
with the used earlier mechanism, the necessity in the intermediate loader
passs, that increases a velocity of loading and reduces a file size (for very
large files, because of availability of the table of transitions, the file
size of a new format can be a size more previous). As LE the format is
standard, now it is possible to use almost anyone of stub, understanding this
format. The files LE of a format can be compressed by the programs of a type
UPX.EXE and it similar.

    If you use stub, which then loads DOS4GW.EXE, the beginning of your
program should have a special signature. The compiler automatically will
generate it, if you in the command line or in c--.ini the file will indicate
a key /DOS4GW. Such key to you will be necessary for applying, if you will
use stub 4gs.exe.


Assembly listing of the block of the program.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For want of task to the compiler of an option allowing generation of
assembly listing of the program the very large file is received sometimes, in
which not simply to discover a fragment, interesting for you, of a code.
With the help of of instructions:

#pragma option lst
...
#pragma option lst-

it is possible to select a fragment of a source code of the program, for
which the compiler will create assembly listing.  The number of such blocks
is not limited.


The extension of possibilities for want of calculation in the registers.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For expressions of expression, realizing calculation, in 16 and 32-bit
registers the number accessible of operations is enlarged.

    Alongside with used earlier operators += -= &= |= ^= now it is possible
to use and *= /=. If the right member of such expression in turn will consist
of several operators, the compiler at first will calculate this right member,
and then the operation with appropriation will be made.

    The call of procedures now is possible in any place of expression
(earlier it was allowable only in the beginning of expression).

    I hope, that now is significant less often to you the messages on
impossibility will annoy to use operation in not AX/EAX the registers.


Optimization of an operator 'switch'.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The operator 'switch' now in the compiler can be realized by two methods:
tabulared and method of sequential checks.

    The tabulared method is fastest, and for want of large number of
operators 'case' and for want of to minor difference between maximum and
minimum significances 'case' it still can be and more compact. But he has
also defects: in a 16-bit mode the compiler always uses the register BX, and
in a 32-bit mode, if an operand 'switch' is the register, it the significance
will be desroyed.

    The method of sequential checks was used by the compiler earlier, but in
this version it was changed slightly: the block of comparisons is transferred
in a beginning of a skew field of an operator 'switch', it has allowed to be
saved from 1-2 superfluous 'jmp'. But now compiler can not define, what type
of transition to use for want of to check of significances 'case'. Now it
will be by your care. If the size of a code from a beginning of a skew field
of an operator 'switch' up to the location of an operator 'case' is less than
128 bytes, it is possible to use short transition. In this case you can
indicate an operator 'CASE', that will reduce in generation of a more compact
code. The compiler in warnings will to you suggest about possibility of using
of operators 'CASE'. Use of an operator 'CASE' in cases, when a size of the
block of a code more than 128 bytes will reduce in issue by the compiler of
the message about an error.

    For want of of optimization of a code on a size, the compiler previously
calculates a size of a code, which can be obtained by both methods and will
realize most compact. For want of of optimization on a velocity the advantage
is returned to a tabulared method, if the size of the table is received not
too large.

    For an operator 'switch' the form - 'SWITCH' is entered as well short it.
It can be applied in case the size of the block of a code between the
beginning of a skew field of an operator and operator 'default' (if it is
absent, by an extremity of a skew field of an operator 'switch') there are
less than 128 bytes. The compiler will inform on possibility of using of the
short form in warnings.


Optimization of a code for want of comparisons.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For want of to check of equality or not equalities to zero, if the left
part of expression of a comparison is composite, the calculation of this
expression in the register AL/AX/EAX happens, and then the comparison of this
register with zero is made. But if the last operation of calculation of
expression installs or removes a flag of zero (ZF) in the correspondence with
an outcome, there is no necessity in a consequent comparison. Just this
reasoning has become main for deriving a more compact and fast code for want
of operations of a comparison. Here is how it looks on an example:

// Initial example
#jumptomain NONE
word a,b;
main()
{
  IF ( a + b != 0 ) a = 0 ;
}

    The last 0.236 versions of the compiler are created by the following
code:
SPHINX/SHEKER C - One Pass Disassembler. Version 0.236 Feb 13 2001

test.c-- 7: IF ( a + b != 0 ) a = 0 ;
0100 A11201                   mov     ax,[112h]
0103 03061401                 add     ax,[114h]
0107 85C0                     test    ax,ax
0109 7406                     je      0111h
010B C70612010000             mov     word ptr [112h],0
0111 C3                       ret

    The new version creates a more compact code:
SPHINX/SHEKER C-- One Pass Disassembler. Version 0.237.1 Feb 18 2001

test.c-- 7: IF ( a + b != 0 ) a = 0 ;
0100 A11001                   mov     ax,[110h]
0103 03061201                 add     ax,[112h]
0107 7406                     je      010Fh
0109 C70610010000             mov     word ptr [110h],0
010F C3                       ret


Check of bits for want of operations of a comparison.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    If in the left part of expression of a comparison is written: AX & 5, for
want of calculation of expression contents of the register AX will be changed
by the instruction 'and'. But sometimes there is a necessity in check of bits
without a modification of contents of the register AX. For these purposes it
is necessary to use the instruction 'test'. How to indicate to the compiler
in what situations to use the instruction 'and', and in what 'test'? In the
standard languages C for this purpose the mechanism of priorities is used -
if the expression is made in brackets, the calculation is made it, if is not
present, the check is made. But C-- does not support priorities. For the
sanction of this problem in C-- is decided to use immediately instruction
'test'. Here allowable variants of syntax:

IF ( $test AX,5 )
IF ( ! $test AX,5)
IF ( asm test AX,5)
IF ( ! asm { test AX,5 } )
Return to list version.



0.236 from 13.02.2001


                             Translater's Remarks

     Due to originally Russian speach some sentences and phrases were modified
into  synonimous  or  simplified.  But  when I finished work I found that some
phrases  are  not  used  in English so you should see the following "Runglish"
into  English  dictionary  to make the way to understanding downlying material
clearer. PLEASE, EVERYBODY WHO KNOW ENGLISH WELL, Send me a proper variants of
sentences. 2:454/21.33@fidonet.org, exhu@tut.by. Yury Benesh

                                The Dictionary

"the code of initial initializing" = startup code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                In more detail about changes in the compiler.


Creation of assembly listing.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     With  the help of a padding -lst option of a command line you can receive
together  with  the  executive  file its assembly listing. The listing will be
placed  into  the file with the same name as executive file has and having the
extension  *.lst.  Assembly  listing  is  formed  by  part, independent of the
compiler,  of the code with using the information about the program, stored at
compilation.  All  this  has  resulted  in  some  increase  of the size of the
compiler and slowing down compilations.


The extension of capabilities at operations of matching.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     In  operations of matching in the left-hand operand now is permissible to
use  calculuss  of expression with priorization and operation of an increment,
decrement. For example:

  IF (i=a+2! = 0)...
  IF (i ++)...
  IF (a--)...
  IF (i + = 4 == 0)...

     In  all these examples at first there will be a calculus of expression in
left-hand  part  of  operation of matching, and then will be made matching the
result with the right member of the matching expression.


Mapping of a structure tag on a memory block.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     The  mapping  of  a structure tag on a memory block is alternative to the
pointers  to  structures. As a matter of fact, as a whole, in both these cases
owes to be generated an identical code, but at usage of pointers to structures
(Hypothetical,  since  th  ey  are not implemented in C--) you'll not know the
register  being  used  by  the  compiler  (but  you  can't  avoid usage of the
register).  And the compiler can not know, whether you will use this register,
therefore it is necessary each time to load into regist er the address of this
structure at each reference to a member of structure through the pointer.
     The  alternate way of using the pointers to the structures will allow you
to  select  the  register,  in  which one the address to the structure will be
stored  and  to  keep  track  of  its safety and as required to restore it. To
explain  how  to use mapping a structure tag to a memory block, probably, will
be easier on an example:

struct AA // the declaration of a structure tag
{
  word a [3]; // the first member of the structure
  char b; // the second member of the structure
  long c; // the third member of the structure
};

byte buf [256]; // the memory unit, on which one will be mapped a structure tag

void proc1 ()
{
 ...
 proc2 (#buf); // procedure call with transfer to it as a parameter
                  // a memory block address
 ...
}

long proc2 (unsigned int pointer_to_mem)
{
int i;
  BX=pointer_to_mem; // in BX we shall load the address of a memory block
  FOR (i=0; i < 3; i ++) {// in an array of the member 'a' record -1
    BX.AA.a [i] = -1;
 }
  BX.AA.b=0;
  return BX.AA.c; // to return the contents of the member 'c'
}

     In 16-bit mode for storage of the structure address it is possible to use
the  registers:  BX,  DI,  SI,  BP.  But  it is better for this purpose to use
register  BX.  The registers DI and SI can be used by the compiler at calculus
of  the  address  of multi-ele ment objects. Register BP compiler will use for
working  with local and parametric variables. In 32-bit mode it is possible to
use  anyone except for ESP and EBP register, but registers EDI and ESI must be
used carefully.


Working with members of a structure.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     For  separate  members  of  a  structure it has began possible to receive
their address, size and displacement in a tag of structure. An example:

struct AA // the declaration of a structure tag
{
  word a [3]; // the first member of the structure
  char b; // the second member of the structure
  long c; // the third member of the structure
};

struct BB        // a tag of the second structure
{
  word aa;       // the first member
  AA bb;         // the second member - an enclosed structure
} ss;            // we declare a structure with a tag BB

void proc ()

{
   AX=#ss.bb.b; // To receive the address of a member 'b' of structure 'bb' in structure ' ss'
   AX=#BB.bb.b; // to receive displacement of the same member in the tag 'BB'
  AX=sizeof (ss.bb);     // to receive the size of 'bb' member in pattern 'ss'
  AX=sizeof (BB.bb);     // to receive the size of 'bb' member in the tag 'BB'
}

Dynamic variables and structures.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     Alongside  with  dynamic  procedures,  already  known for you, in C-- has
appeared  capability to use dynamically both variables and structures. Dynamic
variables  and structures are defined as well as dynamic procedures - by colon
before  the start of their declaration. And also as well as dynamic procedure,
dynamic  variable  or  structure will be pasted into the code, only in case of
its usage in the program.
     The  dynamic variables and structures will find a use in libraries. There
is  no  sense  to  use  them  directly  in  the  programs.  Dynamic variables,
structures  as  well as the procedures, have one lack - you don't know in what
place  of the program they will be arranged, and in what order. The dynamicaly
initiated  variables  and  structures in the file will be arranged in the end,
after  dynamic  procedures.  This  their  feature  can  be used, if it will be
necessary,  that the data won't be sprayed among the code, and be clustered in
one place.


Inline-procedures.
~~~~~~~~~~~~~~~~~~

     Inline-procedures  can be dynamic procedures, and can be used as macross.
But  different to macross, inline-procedure, at optimization on speed switched
on,  are automatically pasted in code, and at optimizations of the code on the
size, they are simila r to dynamic procedures and only calls are made.
     But sometimes it happens it is necessary by live optimization on the size
of  the  code, that the procedures were pasted into the code, instead of their
call  was  done. For these purposes is entered the directive #inline TRUE. The
same directive (#inlin e FALSE), is possible at optimizations on speed to make
calls of procedures, instead of their insertion into the code.

     It  Is  important  to  remember,  that  status  of  the directive #inline
automatically  changes at the change of optimization mode. At the optimization
on  speed  the status of #inline directive is set to TRUE, and if optimization
on  code  size  is  set,  the  directive  is set to FALSE. Therefore apply the
directive #inline only after the change of optimization mode.

     One  more  change  in  the  compiler:  the  directives  which  change the
optimization  mode(  #codesize,  #speed  and  directive  #inline ), pronounced
inside  a  procedure  are appliable only to the rest of a procedure, i.e. they
become  local. the changes were globa l if these directives have been declared
outside the body of the procedure.

     Not any procedure can be an inline-procedure. For them exist the same, as
well  as  for macross, limitation. In more detail about these limitations will
be  said  later.  To  define an inline-procedure, it is necessary in the first
line  with  a  name of procedure instead of a character of a dynamic procedure
(':')   to   write  a  keyword  'inline'.  An  example  of  definition  of  an
inline-procedure:

inline int fastcall abs (AX)
{
    IF (int AX < 0) -AX;
}


Elective switching-off of warnings.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     Now  compiler can show 8 types of warnings and, sometimes there are a lot
of  them,  that  becomes  difficult  in  them to orient. Now it is possible to
electively  prohibit issue of warnings. For this purpose in a command line (or
in  the  file C--.INI) it is possible to establish an option /nw=number, where
number  -  number  from  1 up to 8. To these digits there correspond following
types of warnings:

 1 - "Opimization number "
 2 - "Compiler has used the register... "
 3 - "Possible used short operator '... ' "
 4 - "Repeated string "... " "
 5 - "Expansion variable "
 6 - "Returned signed value "
 7 - "'... ' is already defined. Skipped "
 8 - "[Variable/Structure/Procedure] '... ' possible is not used "


Calling API procedures by ordinals.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     In dynamically linking libraries (DLL) unique number, which one is called
as  an  ordinal,  is  linked  to  each  procedure.  Therefore,  except for the
generally  accepted call of an API-procedure by name, it is possible to make a
call by ordinal. Theoretical ly, at usage of a call by ordinal, the loading of
the file should be faster. As in an output file there will not be the lists of
the names of the procedures included, the calls of which are made by ordinals,
the output file can receive little bit smalle r on the size.

     For  the  compiler  to  create a file with the calls of API-procedures by
ordinals, it is necessary to make two things:

     1.  To  permit to the compiler to do it. For this purpose it is necessary
in the options in the command line (or in the file C--.INI) to declare the key
'WO'.

     2. To notify the compiler - what number of an ordinal corresponds to what
name.  Procedures,  for  which  one the ordinal was not indicated, the call by
name  will  be  created.  To establish correspondence between the names of the
procedures and the ordinals i s possible in two ways:

     a).  Automatically,  with  the  help  of  the  option in the command line
'IND=name.dll',  by  which one the compiler will scan this library and imports
from  it  all  the  names  and  ordinals of the procedures. (Only PE-formatted
libraries are acceptable).

     b).  Manually  to  point  in  the  declaration  of the API-procedures its
ordinal.  So: after the name of the procedure the point-symbol is put, and the
ordinal number is followed. An example of the declaration of the API-procedure
with the indicating of its ordinal:

extern WINAPI "user32.dll"
{
   ............
  long MessageBoxA.429 ();
   ............
}

     In  libraries  (DLL),  sometimes  there are procedures without indicating
their  names,  but  the  number  of  an ordinal is indicated. The call of such
procedures  by  name  is  impossible,  but  it is possible to make call by the
ordinal  (if,  certainly you know, f or what this procedure and what it does).
For  this  purpose  in  the  declaration of a API-procedure it is necessary to
invent  for  this  procedure a unique name and to point a substantial ordinal.
Then  in  the program you will address to this procedure by the invented name.
But  if you incidentally will compile such file without key 'WO', this program
will show the message, that given name in the library is not present.

     Unfortunately,  there  are no warranties that thenumber of an ordinal for
given  procedures will not change in the other version of the dynamic library.
Therefore it is necessary use ordinals cautious.


Removing the limitations on dynamic procedures.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     The  limitations on dynamic procedures reduced efficiency and flexibility
of  library procedures of the compiler. Now it's finished. Now you can dynamic
procedures to call other dynamic and ordinary procedures, in general to do all
that is possible to do in ordinary static procedures.

     However  for  dynamic procedures, which one you are going to use as macro
or inline procedure there is some limitations. They are:

     1.  As  macro - procedures it is possible to use only register procedures
(procedures such as 'fastcall').

     2. In macro - procedures it is impossible to use the operator 'return'.

     3. The local variables also cannot be used in macro - procedures.

     Earlier  dynamic  procedures  were  compiled at once, and then, the ready
code of these procedures was pasted into indispensable places of the programs.
Now  compiler  saves  in  memory the source text of dynamic procedures and, as
required,  compiles  them  in  that  place,  where it should be. Such approach
augments  need more RAM and, probably, will diminish speed of compilation. But
the  advantages,  which  are  gi  ven by such approach, as it seems, cost such
minor victims.


The directive #jumptomain (keys -j0 -j1 -j2).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     The  directive #jumptomain executes little bit different functions depend
on the type of an output file.

     Compilation of the file such as *.com and *.exe memory model tiny:

     #jumptomain  NONE  (-j0)  -  in this case upon termination of the code of
initial initializings of the program is not generated jmp on a procedure main.
This  directive  is  necessary  to  use  if  there  are  no others not dynamic
procedures and initiated variabl es before 'main'.

     #jumptomain  SHORT  (-j1)  -  in  this  case upon termination of the code
initial  initializings  is  generated  short  jmp  on  a  procedure main. This
directive is necessary to use, if up to a procedure main there is no more than
128 bytes of the code and data.

     #jumptomain  NEAR  (-j2)  is a condition set by default. Close jmp on the
main procedure is generated .

     Compilation of files *.exe (keys -exe -d32 -w32 -w32c):

     #jumptomain NONE (-j0) - in this case the code of initial initializing is
not generated and control at start is transmitted at once on procedure main.

     In  all remaining cases the code of initial initializing is generated and
the control is transmitted to a procedure main by the instruction call.

     Compilation of *.dll files:

     #jumptomain NONE (-j0) - in this case the code of initial initializing is
not generated and the control at start is transmitted to procedure main.

     In  all  remaining  cases  the  dummie  code  is  generated  and the main
procedure  doesn't  start.  As a matter of fact procedure main in this case is
not necessary.

     The  procedure  main  at  creation  of  DLL  files  should  look slightly
differently, than In other cases:

dword main (dword hInstDLL, reason, reserv)
{
  ...
}
Return to list version.




0.235 from 13.11.2000


32-bit stub for DOS of the programs.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version of  the compiler there were  modifications in a method  of
transfer  of  an  information  from  the  compilated  32-bit  program  to  the
stub-file. Stub-file - c--stub.exe was accordingly changed also.

    The 32-bit DOS-file has in the  beginning standard 'MZ' the exe-file by  a
size of  32 bytes.  If for  want of  option was  given to  compilation of  the
program to join the stub-file, it  the field on a displacement 0x14  (CS:IP in
standard  'MZ'  header)  contains  significance  of  the  register  EIP,  i.e.
address of  an entry  point in  the program.  And the  field on a displacement
0x1C (in standard  'MZ' header has  not precise function)  contains a size  of
memory  in  bytes   necessary  for  work   of  the  program   -  size_code   +
size_post_datas + size_stack. The stub-file joins the beginning of this file.

    In this version of the compiler the  support of the block of a code  using
for transition and work in a 32-bit  mode of a possibility DPMI of service  is
entered. The  source code  of this  block is  in the  startup.h-- file  and is
compiled, if in the command line the option /stub=dpmi or in the file  c--.ini
is  indicated  to  write  a  line  stub=dpmi.  By  defect  of  this  method of
transition and the work in a 32-bit mode are necessity of mandatory  operation
on the started computer  DPMI of service. Also,  as, the program is  loaded as
usual  DOS  the  program,  and  only  during work passes in 32-bit operational
mode, the  code sizing  is limited  to a  size free  DOS of  memory.  Well and
advantage it is the compact size of an executable file.


Comparison of variables of a type float with the 32-bit register.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In  the  registers  can  contain  signed,  unsigned and material datas. By
default it is  considered, that in  the register is  unsigned an integer.  For
want of comparison of  variables of a type  float with the 32-bit  register it
is  possible  to  specify  a  data  type  contained  in the register. For this
purpose  it  is  possible  to  use  modifiers:  'signed', 'unsigned', 'float'.
Examples:

float f = 1.0;

void PROC ()
{
  IF (f < signed ECX) 	// in the register ECX is signed number
  IF (unsigned EBX > f) // in the register EBX is unsigned number
  IF (f == float EAX)   // in EAX is number of a format float
}


Rapproachement C-- with the standard on the languages C.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In  this   version  of   the  compiler   the  number   of   modifications,
approach-correcting syntax of language C-- with the standard on the  languages
C is conducted. Some from  these modifications create redundancy, but  it will
be easier to you to transfer the programs in C--.

    1. The local  variables now can  be declared and  in the beginning  of the
block of a procedure. An example:

void proc ()
{
int locproc;   // the declaration of a local procedure
  locproc = 0; // and now skew field of a procedure went
int locproc;   // and on this declaration of a variable the compiler will
               // issue the message about an error, since already began a
	       //skew field of a procedure
}

    The declaration of local variables between the declaration of the name of
a procedure and block of a procedure is supported on former.

    2. To numerical constants  it is possible to  write the suffixes 'L',  'U'
and  'F'.  Actually  these  suffixes  in  C--  now  do  not play any role, the
compiler simply swallows them. An example:

# define DEF  1L
# define DEF2 2Lu
# define DEF3 3.0F

    These suffixes  do not  depend on  the register,  i.e. it  is possible  to
write them both small, and large letters.

    3. There  were modifications  in a  gang of  data types. For compatibility
with  the  standard  the  new  reserved  words are entered: 'short', 'signed',
'unsigned'. For  a type  'int' in  a 32-bit  mode the  word length is changed.
Here the table of all variants of new data types:

--------------------------------------- ------------------
|     Full type      | allowable reductions| old analogs |
--------------------------------------- ------------------
| signed char        | char                | char        |
| signed int         | signed, int         | int/long    |
| signed short int   | short, signed short | int         |
| signed long int    | long, signed long   | long        |
| unsigned char      | ---                 | byte        |
| unsigned int       | unsigned            | word/dword  |
| unsigned short int | unsigned short      | word        |
| unsigned long int  | unsigned long       | dword       |
--------------------------------------- ------------------

    The old types 'byte', 'word' and 'dword' are supported on former and  have
functionally former  significance. The  modifications have  touched only  type
'int'. It in  a 16-bit mode,  as well as  a type 'unsigned  int' has a  16-bit
size, and in a 32-bit mode these both types have a size in 32-bit.

    If  you  in  the  32-bit  programs  used  variables  of  types  'int', for
compilation of  these programs  by the  new compiler,  you should  rename them
into  a  type  'short'.  Differently  your  programs  can  work not correctly.
Fortunately old type 'int' is used  in the 32-bit programs not so  frequently.
From the programs,  being available at  me, it was  necessary to make  changes
only  to  three  heading  files  for  windows.

    Expressions of a type: DSINT [..], ESINT [..] I work, as and before.


Initialization DLL for want of to loading.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Sometimes,  for  work  of  procedures  from  dynamic  libraries  (DLL), it
happens necessary to initialize  some variables by significances  dependent on
a  current  condition  of  an  operational  system,  for example, to receive a
descriptor  of  this  library.  For  this  purpose  in  the new version of the
compiler  for  want  of  creation  DLL  the  support  of a procedure 'main' is
entered. The management on  this procedure is transmitted  single-valuedly for
want of to loading of library.

    If  your  library  does  not  require  initialization, and you do not have
necessity to use  a procedure 'main',  by the instruction  #jumptomain NONE or
key of  the /j0  command line  it is  possible to  disconnect requests  of the
compiler in necessity of a procedure 'main'.


Creation of obj-files for 32-bit DOS.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    At last that the generation of obj-files for 32-bit DOS is made. For  this
purpose in the command line it is  necessary to you to indicate keys /d32  and
/obj. To use the  obtained obj-file to me  it was possible only  with the help
of wlink and expander  zrdx.exe. If you will  manage to use the  obj-file with
the help  of tlink,  or with  what or  in another  way, inform  on it  me. The
example of use of the obj-file can be looked in the EXAMPLE directory.


Creation and use of the debug information.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    If at compilation of  the program in the  command line to add  a key /dbg,
or in the file of a configuration c--.ini to add line dbg, the compiler  after
ending compilation will create the file with the debug information. This  file
has a name of the main unit and has the *.tds extension.

    The debug  information created  by the  C-- compiler  is compatible to the
debug  information  of  the  Borland  corporation,  created by compilers. But,
while, this information is  realized yet in full  size. The created now  debug
information has enough for realization of the elementary program debugging.

    For 16-bit programs under DOS for  debugging it is necessary to use  Turbo
Debugger from a package Borland C v4.5 or better (td.exe file).

    For programs  under Windows  it is  necessary to  use the  32-bit debugger
from the same package (td32.exe file).

    For 32-bit  programs using  the expander  DOS to  apply for  the debugging
Turbo Debugger  is impossible.  But, there  can be  I do  not know,  how it to
make). If  you know  how to  create 32-bit  programs with  the DOS-expander by
compilers  of  the  Borland  corporation  with  inclusion in them of the debug
information, tell to me. And I shall try to apply it for C -.

    For want of  start for a  debugging of the  programs, the debugger  should
load it  and to  execute startup  a code,  i.e. to  reach a procedure main and
there to  stay. For  any not  clear reasons,  for want  of to debugging of the
programs  under  DOS  (behind  an  elemination  of  files  compiled with a key
/texe), the  debugger, only  loads the  program and  stays on  first byte of a
startup-code. With it, certainly, it is possible to reconcile, but it is  very
not  convenient.  That  not  tracing  the  startup-block,  is  possible in the
debugger to press keys  'Alt+V', then 'M', from  the list of obtained  modules
to select the module with the name of the debugged file. In the opened  window
to place  a cursor  by the  beginning of  a procedure  main and to press 'F4'.
After that it is possible to begin a program debugging.
Return to list version.




0.234 from 01.10.2000



The declarations of API-procedures.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Some compilers  create DLL,  in which  the names  of exported procedures
have such format:

   ProcName@8

    In this  name after  a char  '@' the  size of  the stack with parameters
transmitted to a procedure is underlined.

    C-- now  can work  with such  of DLL.  To declare  such procedures it is
necessary so:

extern WINAPI "name.dll"
{
   ProcName@8;
}

i.e. without parentheseses. In the  program for want of circulation  to such
procedure it  is necessary  to write  it a  name without  the suffix @8 i.e.
here so - ProcName (param1, param2);



Import of names of procedures from DLL.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    If you want  in the program  to use DLL,  for which there  is no heading
file with the description of procedures, the compiler can import names  from
this of DLL. For this purpose you should indicate a name of this library  or
through an option of the command  line /ind=name.dll, or in the INI  file by
a line ind=name.dll, or through the instruction #pragma option ind=name.dll.

    To defect of such  method of deriving of  names it is possible  to refer
that for want  of compilations of  the program the  library, from which  the
names are imported,  is necessary to  be present at  the computer. Also,  if
the names in library are written without the suffix '@number', the  compiler
will  not  inspect  number  of  parameters  transmitted to a procedure. And,
infortunately, the compiler  knows how to  import names from  libraries have
only format of the PE-file.



Replacement stub in the programs under windows.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    As is known,  in the programs  under windows there  is DOS a  stub, with
which i  is passed  the control  for want  of start  of such program in pure
DOS. Usually such  stub removes on  a screen the  message that this  program
should be started in a medium windows.

    You can instead of standard stub  use. For this purpose it is  necessary
to you to  indicate a name  of the 16-bit  EXE-file or through  an option of
the  command  line  /ws=filename,  or  line  in the INI-file ws=filename, or
instruction #pragma option ws=filename.

    Thus,  at  you  the  possibility  has  appeared  to  create the programs
working and under DOS and under windows.



The interdiction of connection stub to the file.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    With the  help of  options of  the /ns  command line,  or line ns in the
INI-file, or instruction  #pragma option ns  are possible are  to prohibited
with connection stub now and to  the programs under windows (earlier it  was
possible only for DOS32). The start  windows of the program without stub  in
a medium DOS will reduce in unpredictable outcomes.



Link of resources.
~~~~~~~~~~~~~~~~~~~

    Probably, many already have noticed,  that if to windows to  the program
compiled with  the instruction  #winmonoblock TRUE  to link  resources, such
program, more often, does not work.

    By the reason it was that the  programs link resources do not look at  a
virtual size of the last section  of the table of objects, and  calculate it
from a physical size of section.  Therefore, if last there was a  section of
a code, in which there is a  large number of the not initialized datas,  the
physical size  of this  section aligned  on Object_Align  appears less  than
virtual size indicated  in the field  Virtual_Size in the  table of objects,
the page with resources in memory was intersected with page of a code.

    To avoid  it, for  the not  initialized datas  there is separate section
.bss,  which  places  by  very  first  in  the  table of objects. Thereby at
consequent section of a code the virtual size appears equal aligned  natural
and does not happen intersections to section of resources.

    Section  .bss  forms  automatically  for  want  of  compilations  of the
programs with a key /w32. If you  want to have this section and for  want of
compilations of the programs with keys /w32c or /dll to you it is  necessary
to  add  or  in  the  command  line  an  option  /wbss,  or line wbss in the
INI-file, or instruction #pragma option wbss.

    The use of  section .bss practically  does not influence  a size of  the
received file. Theoretically, for processors, which have separate cache  for
datas,  use  of  section  .bss,  should  increase  a velocity of work of the
program.
Return to list version.


0.233 from 11.09.2000


    For want of of optimization on a velocity, on processors Pentium the
instruction MOVZX is substituted with a pair of the instructions XOR and MOV.
But for want of it sometimes there were situations, when the error code was
received. An example:

   Line of a source code:

   EBX = DSBYTE [EBX];

   For want of it the following code was generated:

   XOR EBX, EBX
   MOV BL, DSBYTE [EBX]

   For want of fulfilment such code inevitably will call failure of the
program.

    In the new version of the compiler such situations are watched and are
not supposed.



    The optimization of a generated code on a size and on a velocity is
continued fulfilment:

 - Replacement of division on multiplication:
     As is known, division the slowest instruction of the processor. For want
     of division by variable on number, if it the significance does not
     exceed 65535, the division is possible to replace with more fast
     performed multiplication. An example:

	 Line of a source code:

	 dword a, b;
	....
	 a = b / 12;

	 For want of it the following code will be generated:

	 mov eax, [b]
         mov edx, 15555556
         mul edx
         mov eax, edx
         mov [a], eax

	New numerical significance, on which the variable will be multiplied,
	is calculated by the compiler under the following formula:

	 New_const = 0xFFFFFFFF / old_const + 1

	To calculations with variables of types int and char is applied
	slightly other code, but algorithm remains same.

 - The addition of two 32-bit registers and numerical significance is made
   by the instruction LEA. Examples:

    EBX = EAX + EDX;        - the code LEA EBX, [EAX + EDX]
    EAX = EBX*4+ECX+0x1234; - the code LEA EAX, [ECX + EBX*4 + 0x1234]

    The application of the instruction LEA reduces a size of a received code
    and increases velocity of fulfilment, however, for processors Pentium it
    increases probability of origin of situations AGI with the previous code.

 - For want of multiplication of a numerical constant on a variable the
   exchange by places is made multiplicands, that results in deriving a more
   compact code.
Return to list version.




0.232 from 31.08.2000

    Since  this  version  the  compiler  C--  ceases  to leave in two variants
(cantilever and DOS version). Now there  will be only one 32-bit version  with
by the expander DOS. In this connection the minimum requests to are  increased
to the computer on which is capable to work the compiler. These requests  such
- 386 computers with two megabytes of the main memory (but are better four).

		 In more detail about modifications in the compiler.

Modifications in parameters of the command line.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For improving interaction  of the compiler  with a working  envelope (IDE)
to  to  parameters  of  the  command  line the parameters performing functions
earlier are added the certain instructions.

    Two completely new parameters are added:

/AC (Align Cycle) - makes alignment of a beginning of a cycle on address
     multiple 8. It should increase speed of a code and use a sense to use
     for Processors Pentium.

/MIF= (Main Input File) - transmits to the compiler a name of main
     the compiled module. This parameter is intended for use in files of
     initial initialization *.ini.

    Here full an argument list of the command line and their description:

/2          80286 code optimizations
/3          80386 code optimizations
/4          80486 code optimizations
/5          Pentium code optimizations
/6          Pentium MMX
/7          Pentium Pro
/8          Pentium II
/9          Pentium III till it the optimization is not present any
            information
  	    default 8086
            For 32-bit programs 80386
/A          Enable address alignment
	    default enable, supports inversion
/AC         Align start cycles
	    default is not present, supports inversion
	    It is meaningful only on processors Pentium and better
/AL=**      set value insert byte
/AP         Align start procedure
	    default is not present, supports inversion
	    It is meaningful only on processors Pentium and better
/ARGC       Insert parse command line
	    default is not present, supports inversion
/AT         Insert ATEXIT support block
	    default is not present, supports inversion
/C          Insert CTRL  ignoring code
	    default is not present, supports inversion
	    It is meaningful only under DOS programs
/CRI        Not check include file on repeated
	    default yes, supports inversion
/D32        EXE file (32bit code for DOS)
	    default COM
/D= defined identifier
	    default is not present
/DE         Enable temporary expansion variable
	    default is not present, supports inversion
/DLL        DLL for Windows32
	    default COM
/EXE        DOS EXE file (model SMALL)
	    default COM
/HELP /H /? Help, this info
/IA         Assembly instructions as identifier
	    default is not present, supports inversion
/IP=  include file path
	    default is not present
/IV         Initial all variables
	    default is not present, supports inversion
/J0         Disable initial jump to main ()
	    default is not present, supports inversion
	    In COM-files jmp on main does not create. In others the block is
            not created of initial initialization of the program, and the
            handle is transferred at once on main.
/J1         Initial jump to main () short
	    default is not present
	    It is meaningful only in COM-files
/J2         Initial jump to main () near
	    default yes, supports inversion
	    It is meaningful only in COM-files
/LAI        List of assembler instructions
/ME         Display my name and my address
/MER=**     set maximum number errors
	    default 16
/MIF= main input file
/NS         Disable stub (for DOS 32bit)
	    If the name of the stub-file - is indicated it is authorized
/OBJ        OBJ output file
	    default COM
/OC         Optimize for code size
	    default is not present, supports inversion
/ON         Enable optimization number
	    default is not present, supports inversion
/OS         Optimize for speed
	    default yes, supports inversion
/OST        Enable optimization string
	    default is not present, supports inversion
/P          Insert parse command line
	    default is not present, supports inversion
/R          Insert resize memory block
	    default yes, supports inversion
	    It is meaningful only in DOS-files
/S=*****    set stack size
	    default 2048
/SA=****    start code address
	    It is meaningful only in COM-files, by default 0x100
/SOBJ       Slave OBJ output file
	    default COM
/STM        Startup code in main procedure
	    By default is not present, supports inversion
	    It is meaningful only in COM-files
/SUV=****   start address variables
	    It is meaningful only in COM-files, by default /SA is equal
/SYM COM    file symbiosis
	    default COM
/SYS        Device (SYS) file
	    default COM
/TEXE       DOS EXE file (model TINY)
	    default COM
/UST        Use startup code for variables
	    It is meaningful only in COM-files
	    default is not present, supports inversion
/W          Enable warning
	    By default is not present, supports inversion
/W32        EXE for Windows32 GUI
	    default COM
/W32C       EXE for Windows32 console
	    default COM
/WF=  direct warnings to a file
	    default is not present
/WFA        Fast call API procedures
	    By default is not present, supports inversion
	    Only under windows
/WFU        Add Fix Up table (for Windows32)
	    By default is not present, supports inversion
	    Only under windows
	    For DLL is installed in yes
/WIB=*****  set image base address
	    By default 0x400000
/WMB        Create windows mono block
	    default yes, supports inversion
	    Only under windows
	    For DLL is installed in is not present
/WORDS      List of C - reserved words
/X          Disable SPHINXC - header in output
	    By default yes, supports inversion
	    Is disconnected if is J0

The note: the expression "supports inversion" means, that for the given
option it is possible to use and opposite value with the help of character
'-' ambassador options.


 The file of initial initialization *.ini.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Earlier compiler  automatically searched  and loaded  the file  of initial
the initialization c--.ini at first in  the current directory and if it  there
was not is found, in the  directory, from which the compiler was  started. Now
this file can  have any name  (but the extension  should be necessary  ini). A
name it the file with the  extension should be transferred to the  compiler in
the  command  line.  The  file  c--.ini  is  loaded and is treated on former -
automatically before loading the file indicated in the command line.

    Thus, the *.ini file  can be used similarly  to the make-file -  in it You
can indicate and name of the  main compiled module and all, necessary  for it,
compilations of set-up.


Optimization of a code on speed.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For the processor Pentium the  number of the recommendations, raising,  is
executed speed of a code of the program. Namely:

  - In operations of a comparison of the register with zero instead of the
    instruction OR is used TEST.
  - Are replaced of the instruction CDQ, NOT, NEG, MOVZX, LEAVE on analogs,
    there, where it was possible.
  - For want of multiplication on 2, 4, 8 instead of the instruction LEA the
    shifts are used.
  - The alignment of a beginning of procedures is entered and cycles (is
    included option from Command lines).

    All  these  updatings  are  not  applied  to  a  code,  of  generated from
assembly, the instructions.


Problem with creation DLL.
~~~~~~~~~~~~~~~~~~~~~~~~~~

    Problem which is not  allowing at last is  decided is rigorous to  use DLL
created  by  the  C--  compiler.  Due  to  researches  Denis Porfiryev (FIDO -
2:5066/68.2)  was  clarified,  that  for  want  of generations of the table of
transitions happens the error, because of which did not happen  initialization
of the tables  of transitions and  import. The initialization  of these tables
and in  case the  table does  not happen  the transitions  are not in separate
section.  Therefore  for  want  of  compilations  DLL  not use the instruction
#winmonoblock TRUE.
Return to list version.



0.231 from 16.07.00

Support of procedures 'ABORT', 'ATEXIT' and 'EXIT' for Windows.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The  procedures  'ABORT'  and  'EXIT'   are  connected  to  work  of   the
instruction #atexit both by procedure 'ATEXIT'. Optimal their realization  and
mutual integration can  make only compiler.  For this reason  these procedures
are supported by the compiler. The  support of these procedures under DOS  was
already made earlier.

    The procedure  'ATEXIT' -  register procedure,  which registers  function,
which address is transmitted to it  as a parameter, i.e. through the  register
EAX, both function  of completion of  the program. For  want of to  successful
registration 'ATEXIT' returns 0. In total it is possible to register up to  16
functions.

    The  finishing  functions  should  not  have  parameters and return. These
functions  will  be  executed  in  the   order  a  converse  of  sequence   of
registration in  case You  will finish  work of  the program  through calls of
procedures  'ABORT'  or  'EXIT'  or  the  work  of  a procedure 'main' will be
completed. If  you finish  work of  the program  by procedure call ExitProcess
under  Windows  or  call  AH=0x4C;  $int  0x21  under DOS, withdrawal from the
program will happen without start of the registered functions.

    Procedure 'ABORT' and 'EXIT', if  not the instruction #atexit is  included
do procedure call ExitProcess under Windows and call AH=0x4C; $int 0x21  under
DOS.  Any  parameters  are  not  transmitted  to  a  procedure 'ABORT', and it
finishes work  the programs  with a  return code  0. To  a procedure 'EXIT' is
transmitted in quality  parameter a return  code, with which  it also finishes
work of the program.


The instruction #pragma strtup.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    By the instruction  #pragma startup it  is possible to  indicate function,
which will be  executed before start  of a procedure  'main'. This instruction
has such format:

#pragma startup procname

    Amount  of  time,  which  is  possible  to  apply  this instruction in one
program is not  limited, but really  it is possible  to use some  thousands of
time.


The extension of area of use of a numeral '$'.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The numeral '$', besides that is an indication of consequent assembly  the
instructions, in language C--, as  well as in language Assembler  can specify,
current,  address  (offset)  of  the  compiled  program.  But  in  C-- it had,
limited,  possibilities.  It  could  be  used  only  as  argument in operators
GOTO/goto  and  assembly  instructions  DW/DD/JMP  also  should be necessarily
first in calculated expression.

    Now this numeral can be in any place, of calculated, numerical  expression
also  can  be  applied  in  any   place  together  with  other  by   numerical
expressions.


Extensions of area of use of an operator 'sizeof'.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    If  to  an  operator  'sizeof'  as  a  parameter  to  indicate a name of a
variable, in  the program  the size  of memory,  assigned under  this variable
(earlier this the size such as a variable) was inserted.

    I  accent  your  attention  to  modifications,  occured  for  want  of use
operator 'sizeof' with  the name of  a structure. Now  such expression inserts
the actual size of  memory taken by a  structure (earlier was inserted  a size
tag of  a structure).  It especially  is important,  if you  have declared  an
array of structures.

    The operator  'sizeof' applied  to a  tag of  a structure  as before, will
insert size of this tag.

    The  operator  'sizeof'  now  is  possible  to  apply  and to the name, of
determined earlier, procedures. An outcome will be a size of this procedure.


Problems with compilation DLL.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    At  use  DLL,  written  on  C--,  was  clarified,  that  at  loading these
libraries to occur  initialization only tables  of export. The  tables movings
and import, on not clear to me to the reasons are not initialized. I shall  be
Is glad to any help from you, allowed to solve this problem.

    I  assume,   that  this   initialization  is   made  with   the  code   of
initialization  libraries.   It  would   be  desirable   to  see    documental
confirmation it both the detailed description of this process.

    This problem superimposes, very much I  hope that it not for a  long time,
limitation on use  DLL written on  C--. And limitation  these here such  - the
procedures which  are taking  place, in  DLL should  correspond to  all of the
requirement, which  are showed  to dynamic  procedures, i.e.  they should  not
comprise calls  of other  procedures and  to not  address to global variables.
They nor should include string constants.
Return to list version.




0.230 from 13.06.00

The file of a configuration c--.ini
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Now compiler  searches for  the file  of a  configuration at  first in the
current directory and, If  it there will not  appear, in the directory,  where
compiler is  located. It  Will allow  to use  the file  of a configuration for
customization of the concrete project.


The simplified input of the assembly instructions.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Has become possible  to use the  assembly instructions without  the prefix
'$' and  outside of  the block  asm. This  mode is  included: from the command
line by an option  /ia; in the file  configurations by line ia  or instruction
#pragma option ia.

    When this mode is included, all names of the assembly instructions  become
by reserved words,  i.e. You can  not these names  use in quality  of names of
variables or  procedures. The  assembly instructions  the compiler  recognizes
irrespective of, they are written by small or large characters.


The list of the supported assembly instructions.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    To  receive  the  list  of  the  assembly  instructions,  supported by the
compiler, It is possible, by starting the compiler with an option /lia.


The instruction include.
~~~~~~~~~~~~~~~~~~~~~~~~~

    For the instructions  'include' and 'includepath'  of path now  is written
without double characters  '\\'. For the  instruction 'include' the  alternate
variant of search has appeared the  file, in which the search of  the included
file occurs  in, opposite,  direction -  at first  in the  directory, in which
there is  a compiler,  then in  the directories,  on which  are specified by a
variable of environment C--, then in the directory by the entered line of  the
ip=path in c--.ini file, then in the directory by the entered option  /ip=path
from command lines. The search in the current directory is not made. That  the
search of the included file occured  on this algorithm, the name of  this file
is necessary to include in angular quotes.  For example:

 #include < system.h-- >


Syntax of parameters of the command line.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The  options  to  the  compiler  in  the  command line now can be selected
except for character '/' also in  character '-'. To invert the function  of an
option it is possible in character '-' after options.

Examples:

Commands
/on And -on are acceptablis and functionally identical.
For a cancellation of this option it is possible to write down:
/on- Or -on-

    Syntax in the C--.INI file command  in it accordingly has varied also  the
file are written  precisely as well  as in the  command line behind  exception
first identification character '/' or '-'.



Skip of the repeatedly included file.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    More often,  repeatedly to  include the  file in  the compiled project, is
not present  necessities, but  it sometimes  occurs that  some, included,  The
files include  other files.  That it  did not  occur it  is necessary  To make
check on repeated loading of the  file. Now this function incurs the  compiler
and at you passs necessity to make this check.

    But  sometimes  (is  very  rare)  there  is  a  necessity to make repeated
inclusion the file.  For this purpose  in the compiler  there is an  option of
the /cri-  command line,  which prohibits  to the  compiler to  make check  on
repeated inclusion. Accordingly, For  c--.ini of the file,  it can be made  by
line cri- or instruction in the compiled file #pragma option cri-.


Skip of the struct key word.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    If  you  declare  structure  with  an  already earlier defined tag by this
structures,  the  'struct'  key  word,  as  well  as  in other languages C, is
possible to not write, and to specify at once name of a tag. For example:

// We declare a tag of structure
struct EXAMPL
{
  int a;
  long b;
  char c [6];
};

...

// The declaration of structure as was earlier
struct EXAMPL s1;
// Now it is possible to make and here so
EXAMPL s2;
Return to list version.



0.229 from 06.04.00

The extension of a file name with the main module of the source program.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Earlier main module of the compiled program could have *.c--  extensions
or *.cmm. Now  compiler supports four  extensions of a  file name. It:  *.c;
*.h--; *.hmm; *.h. It  will allow you to  use the editors from  compilers of
other languages.  If you  in the  command line  will indicate  only name the
file without the extension, the compiler  will try to open the file  with it
by the  name and  with sequentially  connected extensions  in the  following
order: *.c--; *.cmm; *.c; *.h--; *.hmm; *.h.


Process of scaling of address.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    To facilitate choice of an element of  an of the same type array in  the
compiler automatic process  of scaling of  address depending on  earlier was
entered declared  type of  an array.  It allows  for want  of circulation to
array  cells  to  specify  their  serial  number  instead  of  an   absolute
displacement. It the automatic  process of scaling acts  only in case if  in
quality index the variable either any expression or register, which is  used
can  not  be  used  in  generation  of  indirect  address  of  assembly  the
instructions (for a 16-bit mode are  the registers AX, CX, DX). For  want of
use  in  quality  of  an  index  of  a numerical constant either register or
combination  of  the   registers  from  which   can  receive  the   assembly
instruction the compiler this  index not scales as  an array, i.e. in  datas
cases is used absolute addressing in an array. For example:

word buffer [10]; // an array from 10 elements of a type word
int i;

Proc ()
{
  ...
  buffer [i] = 0;  //the variable i specifies number of an array cell buffer
  buffer [3] = 0;  //number 3 is an absolute displacement in an array,
                   //i.e. zero will be noted to the address #buffer + 3
  buffer [BX] = 0; //the register BX also contains an absolute displacement
                   //in an array
  buffer [AX] = 0; //and the register AX already will contain a serial number
                   //of an element of an array
 ...
}

    Such duality is explained  to  that earlier  as an index it  is possible
was  to  specify  only  numerical  significance  or  registers,  which it is
possible to use for want of  indirect addressing in the instructions of  the
assembler. For compatibility with the old programs this position was  saved,
and  all  the  consequent  new  types  of indexes, which were not supported,
earlier now are used as numbers of array cells.

    But this innovation had also  negative by-effect. In C-- elements  array
buffer[idx]  and  absolute   addressing  through  expressions   of  a   type
DSWORD[idx] understand  with one  procedure of  the compiler,  therefore and
expressions type DSWORD[idx] has become  to happen process of scaling,  that
is logically incorrect.

    In this version the  corrective amendments permitting are  introduced in
this  procedure  to  divide  these  expressions,  therefore the compiler has
become to issue more logically correct code.

    Possibility incidentally was added to disconnect process of scaling  and
for want  of the  circulation to  an array  cell (I  do not  present in what
cases it can it is useful). It  is possible to make by delivering before  an
index a char '*'. For example:

  buffer [*i] = 0; //here variable i will contain an absolute displacement in
                   //array, instead of number of an element.
Return to list version.




0.228 from 08.03.00

    New group of internal procedures-macro.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Use of internal procedures-macro allows  to receive in many  respects
cases  a  more  compact  and  fast  code.  It  is explained to that disappears
necessity to  transform transmitted  and returned  parameters in intermediate,
convenient  for  transfer,  condition.  In  this  version  of  the compiler to
already to  existing group  of procedures  of input-output  in ports, is added
large  group  of  mathematical  procedures  working with material numbers also
variable type float.

    Here the brief description of these procedures:

float atan (float x);     - calculate arctangent of number x.
float atan2 (float x, y); - calculate arctangent of the attitude x/y.
float cos (float x);      - return cosine of a corner x.
float exp (float x);      - return to an exhibitor of number x (erects the
                            basis the natural logarithms in a degree x).
float fabs(float x);      - calculate absolute value of number x.
float log (float x);      - calculate the natural logarithm of number x.
float log10 (float x);    - calculate the decimal logarithm of number x.
float sin (float x);      - return a sine of a corner x.
float sqrt (float x);     - take a square root from among x.
float tan (float x);      - return tangent of a corner x.

    All corners in these procedures should be given in radians. In quality
parameters these procedures can use as integers, and variable whole types.
The compiler automatically will transform them in material type.



    Merge of identical line constants.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version of the compiler the new mode of optimization - merge is
entered identical line constants. If this mode of optimization will be
enabled, the compiler will remember all line constants and at detection
identical into a code of a file will not be inserted repeated line the
constant, and will be made the reference to first, found out earlier line
constant. The not called lines constants participate only in optimization.
I.e. if the file or structure will be initialized by a line, such the line
will not participate during initialization, so this line can to be changed
during work of the program. An example:

char var = "test"; // this line will not participate during optimization.

void proc ()
{
    WRITESTR ("test"); // this line will participate in optimization.
    AX = "test";       // variable AX the address of a line, which will be
                       // appropriated was inserted into a code of the
                       // program in the previous line.
}

    About all cases of detection of a repeated line the compiler will give
out the warning.

    Enabled this mode of optimization or from a command line /ost, or is
included by the instruction #pragma option ost, or line in a file c--.ini -
ost. To disconnect, included earlier, this mode is possible by the
instruction #pragma option -ost.


    Installation of the identifier in TRUE from a command line.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    If you have written the program, which can be compiled on any other
business, in dependences on a condition of some identifiers (the mode is used
the conditional compilation), to you very much needs this option.
Establishing with command line various identifiers you can receive various
variants of the program not editing the sources text of the program.

    The identifier is entered from a command line by a key /d=idname.
Return to list version.




0.227 from 09.02.00

Initialization of local variables at their declaration:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Purely, it seems, to explain here nothing it is necessary. All and so is
clear.  Is unique I shall tell, that there are some limitations. It is
impossible to initialize the arrays and many-dimensional structures. It is
possible to initialize by one value, â.¥ it is impossible at initialization
of local variables to use transfer made in curly brackets and operators FROM
and EXTRACT.


Control behind number and types of parameters, transmitted to the push-down
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 procedure:
				 ~~~~~~~~~~

As is known, in C-- the control behind number and type of parameters,
transmitted to the procedure, was assigned to the programmer. Therefore there
was a unsimplis task to combine simultaneously absence of a control behind
parameters (for compatibility with the previous versions) and it presence. As
a result of the compromises the variant little bit distinguished from
traditionally accepted in languages C has appeared.

The main difference is that the parameters defined at definition of the
procedure, will not be perceived by the compiler for a control behind them.
In all languages C overlapping the prototype of the procedure and it of the
declaration is accepted. In C-- that the control behind parameters of the
push-down procedure has joined, it is necessary this procedure necessarily to
declare. But not any declaration of the procedure will a signal to the
compiler about inclusion of a control behind parameters of this procedure. If
at the declaration in parentheseses nothing will be, the compiler will not
watch parameters transmitted to this procedure. In C++ such declaration
means, that any parameters are not transferred to the procedure. In C-- for
this purpose it is necessary at the declaration of the procedure in
parentheseses necessarily to write void. For example:

int proc (void);

By meeting such declaration of the procedure the compiler will watch(keep up),
that the parameters were not transferred to this procedure.

At the declaration of the procedure the names of parameters can be omitted.
As is known, in C-- the parameters of the procedure of one type are written
through a comma. For change of a type use a semicolon. At the declaration the
change of a type can be made and after a comma:

void ptoc (int a, b, c; word d);
void proc (int, int, int, word);
void proc (int, int, int; word);

All these examples of the declarations are identical and acceptablis.

For a control behind procedures with variable number of parameters the unit of
syntax - dots was entered new for C-- or it still name the ellipse. The
declaration of the printf procedure here is how will look:

void cdecl printf (word,...);


Operators of a cycle LOOPNZ/loopnz:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The cycles LOOPNZ/loopnz differ from a cycle loop, that before an input in a
cycle the equality to zero of argument of a cycle is checked. If the argument
is equal to zero, the iteration body will be never executed (in a cycle loop
in this case iteration body the maximum number of times) will be executed.
Return to list version.




0.226 from 10.01.00

   Is this version correct bugs:
- The false message on an error was produced in terms of a type:
 intvar = #ucnownlabel + number;
- There was a failure parser at analysis of expressions of a type:
 $ push 8, AX, var
- The incorrect month was generated at use of macro substitution of expression
__DATE__.

The simplified support of character '!' was added - not in operations of
matching if/IF for/FOR while/WHILE. Actually introduction of this character
to operation of matching (character ! can be only first) results in inverting
a flag of check of a condition.  Expressions:

IF (NOTCARRYFLAG)... And IF (! CARRYFLAG)...
IF (proc () == 0)... And IF (! Proc ())...

Are synonyms.

Also code of the compiler was optimized slightly.
Return to list version.





0.224 from 28.10.99

The cantilever variant of the compiler from this version has become more
powerful, than it DOS analogue. At compilation of 32-bit programs on
the cantilever version of the compiler the size of an output file is not
limited.  Some other parameters also are considerably increased also.


At compilation of programs for Windows now all tables, which knows how to
create the compiler (and it while knows how to create the tables of import,
of export and table of movings) are located in one section. It allows to
receive a more compact output file. If you, on what that to the reasons such
subroutine linkage of the file does not arrange, with the help of the
instruction #winmonoblock FALSE you will receive the file with standard
subroutine linkage of the tables.


The instruction #pragma is added also which in turn has the instructions. In
this version the instruction #pragma supports only one instruction - option.
The instruction option allows to include in your code of an option of the
command line of the compiler. Some options can not be used in this
instruction; others should be located right at the beginning of a source
code. An example:

#pragma option w32c

This instruction declares to the compiler, that is necessary to create the
cantilever 32-bit file under windows.


The option of the command line allowing is added to make alignment of a
beginning of procedures by the beginning of the paragraph, that should
raise speed of your programs. This option works only at compilation
of the 32-bit code. By default this option is disconnected. She is
included so:

/ap=true


Macro __DATE__ and __TIME__ represent text string of date and time
of compilation of your file.


For operators BREAK, break, CONTINUE, continue the support of the numerical
parameter defining how many of cycles is necessary to skip is entered before
this operator will be executed. For example we have three nested cycles:

do {
loop (CX) {
for (BX = 0; BX < 10; BX ++) {
	 break; 	 // a standard operator
	 break 0; // break with the parameter - to skip 0 cycles
	 break 1; // break with the parameter - to skip 1 cycle
	 break 2; // break with the parameter - to skip 2 cycles
}
LABL0:
}
LABL1:
} while (DX! = 0);
LABL2:

In the third cycle there is a group of various variants of an operator
'break'.  To first cost a standard operator 'break' at which execution handle
will be transferred for bounds of the third cycle - to a label 'LABL0'.
Second goes an operator ' break 0 ' at which execution 0 cycles will be
missed and the handle will be transferred again on a label 'LABL0'. Thus
record 'break' and ' break 0 ' are synonyms. Third goes an operator ' break 1
' at which execution one cycle will be missed and the handle will be
transferred for bounds of the second cycle on a label 'LABL1'. Well and at
last latter goes an operator ' break 2 ' at which execution the compiler will
skip two cycles and will transfer handle for bounds third to a label 'LABL2'.
Labels in this example sets for convenience of an explanation.  Well
and I hope to you clearly, that the value of the parameter can not exceed
numbers of cycles taking place before current. So for a single cycle this
parameter can accept maximum and unique value - 0.


The syntax of the file c--.ini is simplified. Now in this file use of blanks
and comments is acceptablis. Tag of a beginning of the comment is character
';'. All consequent characters the ambassador ';' and up to the end of string
are considered as the comment. But on former, to each option there should
correspond the string.


For programs for windows there was an availablis instruction #argc, including
in the program the code disassembly of the command line. Accordingly now
it is possible to use and built-in procedures PARAMCOUNT () and PARAMSTR ().
Return to list version.






0.223 from 05.10.99

                          Nested structures.
			  ~~~~~~~~~~~~~~~~~~

    Now at the declaration of tags of structures it is possible to use tags
others, declared before structures. An example of nested structures:

struct RGB
{
  byte Red;
  byte Green;
  byte Blue;
  byte Reserved;
};

struct BMPINFO
{
  struct BMPHEADER header; // the description of this structure is missed
  struct RGB color [256];
} Info;

    Let's assume to you it is necessary to receive contents of a variable Red
tenth Unit color. It can be written down so:

  AL = info.color [10] .Red;

    But there is one limitation of use of nested structures in C--.
It is impossibility of use of a variable more once at call
to math copies to structures. Let's explain it on an example:

struct ABC
{
  int a;
  int b;
  int c;
};

struct
{
  struct ABC first [4]; // 4 copies of structure ABC
  int d;
} Second [4];

int i, j;

void proc ()
{
  AX=second[i].first[j].a; //such record will call the message on an error, so
                           // As the variable was used in two places
  AX=second[2].first[j].a; // and this syntax is allowable.
  AX=second[i].first[3].a;
}


                 New syntax of hexadecimal numbers.
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Now C-- together with traditional C-style of hexadecimal numbers
Understands also numbers written down in style of the assembler. For those
who suddenly not Knows, I communicate, that the hexadecimal numbers in the
assembler have on the end Character 'h' or 'H'. If first character of
hexadecimal number is more '9', That before it character '0' should be
necessary  written down. Examples:

  1234h
  0A000H


                  Rapproachement of syntax with traditional C.
		 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    That it was easier to transfer included files of the C language in C--,
in Syntax of the instructions to the compiler now instead of character '?' It
is possible to use Character '#'.
Return to list version.





0.222 from 19.09.99

           Export of procedures and creation DLL for Windows.
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version the possibility has appeared at programming for
windows to make export of procedures and, accordingly, the possibility has
appeared to receive files of dynamically connected libraries - DLL.

    The dynamically connected libraries will allow to receive more compact
programs and to speed up the process of compilation. To minuses of use DLL
it is possible to relate necessity of presence of files DLL on the started
computer and time of start of the program is increased slightly.

    That the procedure has become availablis for other programs it is
necessary in sources before the name of the procedure to register the key
word - _export.  Example:

  void _export testproc ()
  {
    ....
 }

    To create DLL it is necessary to write the file in which will be
procedures with key words _export. The main procedure in such file not is
necessary. The auxiliary procedures, which can be necessary for operation
main exported procedures to declare as _export it is unessential. Then this
file needs to be compiled with a key /dll. In result you receive the ready
dynamically connected library.

    The note: the code of initialization DLL is in the STARTUP.H-- file,
    ~~~~~~~~~~ therefore before to compile DLL necessarily update this
file. It is in the LIB.ZIP file. As I have not found documentation
describing the process of initialization DLL, this code was obtained
intuitively - experimental by way. If you have such documentation, that,
please, send it to me to the address sheker@mail.ru.


                 Alternate extension of source files.
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    From this version the compiler except for the *.C-- extension
understands and *.CMM. It is made because some editors do not perceive the
C-- extension.


              Syntax of the declaration of API-procedures.
	     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version also syntax of the declaration has varied slightly also
API-procedures. Now after the name of the procedure it is necessary to
register opening both closed brackets and semicolon (earlier it was
unessential). And for procedures of a type fastcall in brackets it is
possible to specify both the registers used at transmission of parameters.
Return to list version.






0.221 from 10.09.99

            Declaration of parameters in register procedures.
	   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The declaration of parameters of register procedures is entered, that
at call of register procedures it was not necessary to count number of
commas before by the parameter of the procedure.

    Earlier to each parameter of the register procedure corresponded strict
the defined register. For example, for a variable of a type int or word
first the parameter was transferred through the register AX, 2-nd - BX,
3-rd - CX, 4-th - DX, 5-th - DI, 6-th - SI. Therefore if it was necessary
to you to transfer only one it was necessary before it to write the
parameter through the register SI, five commas. Here as, for example, the
procedure call STRCPY looks:

void main ()
{
  STRCPY ( , , , , #dest, #sourc ) ;
}

    Now registers can settle down by transmission of parameters arbitrary
by image. It is necessary only to declare to the compiler about what
register is fixed for by what parameter of the given procedure. After such
declaration the compiler will be itself to keep up through what register to
transfer the parameter to the procedure, it by dimension and number of
transmitted parameters. Here is how will look the declaration and use of
the STRCPY procedure:

void STRCPY (DI, SI); 	 // this declaration of the procedure

void main ()
{
  STRCPY ( #dest, #sourc); 	 // and it is procedure call
}

    It is possible to not make the declarations of the procedure, and to
specify layout of the registers in header of the procedure. But then such
procedure should be called only ambassador it of definition. Here an
example of the procedure outputting on the screen a little identical
characters:

void PUTNCHAR (AL, CX, BL, BH)
/* 1 parameter in AL - code of character, which will be output
   2 parameters in CX - number of output characters
   3 parameters in BL - colour attribute
   4 parameters in BH - number of videopage
*/
{
  AH = 9;
  $ INT 0x10
}

    At the declaration of the register procedure it is possible also to
specify what type the variable is expected by the procedure (sign/unsign or
material). On it is considered to default unsign the type. However sign
type to specify there is a sense only if the parameter is transferred
through the register AL/AX/EAX. Through others the registers the variable
is always transferred as unsigned. An example of the declaration the
register procedure with the instruction of types:

int fastcall Exampl( word CX, int AX, DX, float ESI ) ;
 |    |        |        |         |   |   |
 |    |        |        |         |   |   ---- 4-th pairs. Has the float type and
 |    |        |        |         |   |        before. Through the register ESI.
 |    |        |        |         |   -------- 3-rd pairs. Has on default
 |    |        |        |         |            word type and before. Through DX.
 |    |        |        |         ------------ 2-nd pairs. Has the int type both
 |    |        |        |                      is transferred through the register AX.
 |    |        |        ---------------------- 1-st pairs. Has the word type both
 |    |        |                               is transferred through the register CX.
 |    |        ------------------------------- A Name of the declared procedure.
 |    ---------------------------------------- The Modifier indicating, that
 |                                             this proc. is Register.
 --------------------------------------------- The Procedure returns of changes.
					       type int.

    If you have made the declaration of the registers of the procedure, the
compiler will be strict to watch an amount of indicated parameters at call
of this procedure and to produce the messages on an error, if them will be
less or more. With one the sides it is good - there is a control that you
nothing have overlooked or not have added superfluous at procedure call. On
the other hand sometimes are it is necessary to register unessential
parameters, and them now.

    If you have not declared the registers at the declaration of the
register procedure, in header of the procedure, the compiler will count,
that parameters in this the procedure are transferred by an old way. Thus,
is reached full compatibility with the previous versions of the compiler.
Return to list version.





0.220 from 23.08.99

                               OBJ-files.
			      ~~~~~~~~~~~~

    For obtaining conducted (slave) of obj-units in the compiler the key is
added /sobj command lines. For this type of obj-units the limitations on
are removed use of variables.


                        Instruction ?dosstring.
		       ~~~~~~~~~~~~~~~~~~~~~~~~~

    The instruction ?dosstring defines what character will be
the terminator (Terminating symbol) of string.

    If to enter the instruction ?dosstring TRUE, all consequent character
the strings will come to an end in character of dollar - '$'.

    If to place this instruction in FALSE, as the terminator character
strings the zero will be used.

    By default this instruction is placed in FALSE.


            Instruction for compilation of programs for Windows.
	   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Some instructions have appeared which work only at compilation programs
for Windows.

   ?imagebase value - sets the Image Base address. By default this address
is equal 0x400000.

   ?fixuptable TRUE/FALSE - to permit/prohibit creation FixUp of the table
(on it is forbidden to default). As was clarified, program under Windows
perfectly work without section FixUp.

   ?fastcallapi FALSE/TRUE - to prohibit/permit generation of fast call
API-procedures (by default it is authorized). Microsoft recommends such
scheme call of API-procedures - CALL on indirect JMP is made, though itself
uses at once indirect CALL. It allows to receive the little bit faster
code, and if the call of the API-procedure is made from less, than 5 places
of the program, and more the short code.


                     Cantilever version of the compiler.
		    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The cantilever version of the compiler works only in the Windows
environment both uses the cw3220.dll library from a package of the BC
compiler 5.0 or better.

    Functionally DOS and cantilever version of the compiler while are
identical.


                    Substitution of multiplying by shifts.
		   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    At multiplying on number and included optimization on speed the
compiler for obtaining the faster code tries to decompose multiple number
on combination of shifts and additions.


                      Operator of association - union.
		     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The associations allow in different instants to store in one object
values of a various type.

    The memory, which is selected under association, is defined by the size
longest of units of association. All units of association are placed in the
same area of memory from the same address.  The value of a current unit of
association is lost, when to other unit associations the value is assigned.

    In C-- the so-called anonymous associations are realized. I.e.
associations the name is not assigned, and the call to units of association
occurs as to by usual variable. An example:

union
{
  dword regEAX;
  word regAX;
  byte regAL;
}; // have declared, that 3 variables are located on same physical
   // address

Void test ()
{
	 regEAX = 0x2C;
	 BL = regAL; 	 // in the register BL there will be a value 0x2C
}

    To unite it is possible variables of various types, arrays, string
variables and structures. The associations can be global and local, and
also to settle down inside structures (while in associations inside
structures it is impossible to use structures). The global associations can
be initialized and non-initialized. To receive the initialized association
needs to be initialized only first unit of association. If the first unit
of association is not initialized, and the following units are initialized,
it will call the message of the compiler about to error.
Return to list version.





0.219 from 06.07.99

                                OBJ-files.
			       ~~~~~~~~~~~

    Earlier C-- created obj-files, which could be connected to the projects
created on other languages, i.e. conducted (slave) units. And from C--
units for the main project the procedures and these procedures were
availablis only should not use global variables.

    Now C-- can create the main (master) unit, which can to be link in the
independent file. It enables to simplify debugging programs. For example
you have written the program, which or does not work, or works not as it is
necessary. Attempt to use for debugging the TD.EXE debugger is complicated
by that is very heavy to orient in the machine code. Now you can compile
this file with a key /obj, and obtained obj-file link tlink.exe with a key
/v. In result you receive the exe-file with by the minimum debug
information, included in him. By starting this file in the debugger you
will see in machine codes of the name of procedures and variables, that
considerably will facilitate debugging.

    For obj-files the possibility has appeared to use external (extern)
procedures, variable or structures. For this purpose it is enough them to
declare as extern. And the extern key word should be always first. An
example the declarations of external objects:

extern void cdecl _printf(); //the declaration of the external procedure _printf, having,
                             //cdecl type and type of return void
extern int buts, cubs; // the declaration of two external variables of a type int
extern struct IPXL ipxl; // the declaration of external structure ipxl, of having a tag,
			 // IPXL, and the tag of this structure should be
			 // is described earlier.

    Appearance of possibility to declare external objects allows to connect
to the obj-unit on C-- units written on other languages or to connect to
the program on C-- procedure from libraries on other languages. At the
declaration external objects it is very important correctly to specify the
type of the procedure and it a name. If You will use external procedures
written on C that more often, you it will be necessary to specify the
modifier cdecl, and to the name of the procedure or variable to add the
prefix '_'.

    From main (master) of the obj-file written on C-- for other obj-units
all procedures, global variable and global structures are availablis.

    For conducted (slave) of obj-units the situation while practically has
not varied. You on former can use from units on C-- only procedures. And
these procedures should not use global variables, but now in them you can
use external variable and to make calls as other procedures, and external.
To receive the conducted obj-unit in sources it is necessary to add the
instruction ?jumptomain NONE or at compilation to a key /obj it is
necessary key /j0.

    If the obtained obj-file link with a key /s that you receive the
map-file with the detailed information. Has disappeared necessity for
generation C-- map-file, which actually was useless. In this version the
support of keys is removed /-map command lines and /+map.

    C-- can create obj-files with memory model tiny and small. By default
the units with a model tiny are created. To receive the obj-file with
memory model small is necessary to start the compiler with keys /obj and
/exe. Theoretically it is possible to receive and 32-bit obj-units for DOS
(I this moment did not check, therefore there can be any defects). Creation
of obj-files under windows not is stipulated.


                  New modifiers such as calls of procedures.
		 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In the last version the modifier such as procedure call cdecl has
appeared. In this the versions are added to it three - pascal, stdcall and
fastcall. Here brief the characteristics of these types of calls of
procedures:

cdecl This type of call of procedures is by default for the language C. It
~~~~~ is characterized by that the parameters of the procedure are
transferred in the order converse of their record. The clearing of the
stack of parameters is made after completion operations of the procedure.
This way of call of procedures is very convenient for procedures with by
variable number of parameters.

pascal This type of call assumes, that the parameters are transferred in
~~~~~~ that order, in which they are written down in the program. Release
of the stack from parameters called procedure makes. This type of call is
more compact than cdecl.

stdcall This type of call is a hybrid first two. The parameters are
~~~~~~~ transferred to the procedure in the order a converse, that in which
they are written down in to the program. The release of the stack from
parameters is made in, most called, to the procedure.

fastcall This type of call of procedures is assumed that by transmission of
~~~~~~~~ parameters to the procedure is made through the registers, thus
passs necessity of release of the stack from parameters. For this type of
call the procedures exist limitations on number of transmitted parameters.
For C it three parameters, and for C-- six. In with - the parameters are
transferred in, following, the order: 1-st - AX/EAX, 2-nd - BX/EBX, 3 -
CX/ECX, 4 - DX/EDX, 5 - DI/EDI, 6 - SI/ESI. The parameters of types char or
byte can be transferred in an amount not more than 4 or only in the first 4
registers: 1 - AL, 2 - BL, 3 - CL, 4 - DL.

    In C-- by default, if the name of the procedure is written by the large
characters, it is considered, that this procedure has the type of call
fastcall. If in the name the procedures are even one small character, by
default it is considered, that this procedure has the type of call pascal,
except for programs, of compiled, with a key /w32 or /w32c. In them by
default the type of call of procedures is applied stdcall. If you want to
change the type of call of procedures from by default on it is necessary to
declare anyone another, this procedure with the instruction of a type
desirable call.


                        Alignment of data and code.
		       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In C-- there is an instruction ?align, which makes single alignment of
data on the even address. Now, if to this instruction to add the number,
alignment will be made on the address to multiple this number. For example
instruction ?align 4 will add a data segment up to addresses multiple 4. At
alignment the bytes of which value will be inserted are defined by the
instruction ?aligner, by default this value is equal to zero. The
instruction ?align makes alignment only in a data segment. In those memory
models, in which data segment and code coincide this instruction it is
possible to apply and for alignments of a beginning of procedures.

    In this version the new instruction - is added ?aligncode [value],
which makes alignment in a segment of the code on the address to multiple
value value, on to default on the even address. Value of byte of filling in
this instruction is number 0x90 - code of the instruction NOP. Value of
byte of filling for this the instructions cannot be changed. This
instruction can be applied and inside the executed code. For example, if
you want to receive the fast code on 486 the processor, it is recommended
to make alignment of a beginning of procedures and cycles on the address
multiple 16. For Pentium I have contradictory information. In one sources
is written, that for Pentium to align the code it is not necessary, and in
others, is communicated about necessity of alignment on the address
multiple 32. If someone can specify this information, the request to inform
about it me.
Return to list version.





0.218 from 14.06.99

                          Instruction ?startuptomain
			 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Under this instruction the compiler in the beginning of the file makes
jmp on a beginning main() procedures. Before the beginning of compilation of
this procedure the compiler will begin compilation startup of the code and
only then the compilation of the procedure will be continued main(). Thus
startup the code will appear not in the beginning of the file, as it occurs
usually, and in a body of the main() procedure. It will be, useful at
compilation, resident programs (TSR).

    The instruction ?startuptomain works only at compilation of com-files.


                            Instruction ?undef
			   ~~~~~~~~~~~~~~~~~~~~

    This instruction destroys constants declared by the instruction ?define.
It It is possible to apply to change during compilation of value any
constants.


                      Startup-code in the startup.h-- file
		     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Probably many from you were not consent with that of startup the code,
which generate the compiler hands also were scratched to change it. But it
was very difficult, as this code generate the compiler also was not
possibilities to affect it. Now startup the code is born in the separate file
- startup.h--. This file owes is in one directory with other library files.
To include it by the instruction ?include in the program it is not necessary.
The compiler itself will load it in moment, convenient for it.

    Now at you the possibility has appeared to make startup the code on the
taste. But without acute necessity to make it it is undesirable.

    The compiler operates generation the startup-code by means of creation
various constants. Upon termination of generation of the startup-code these
constants are deleted by the instruction ?undef, as they are not necessary
any more. Names of global the labels and variables cannot be changed, as they
will be used by the compiler during further compilation. To select names (
constant, it is impossible to change labels, variable), which, in their
syntax two first character are characters of lower underline.


                 Prefix of repetition of the instructions DB/DW/DD
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For the assembly instruction DB, DW, DD the possibility is entered to use
the prefix of repetitions dup. The application of this prefix has the
following syntax:

  $ DW NUMREP dup VALTOREP

NUMREP - number of repetitions of the instruction DW.
VALTOREP - value, which will be repeated NUMREP of time.

    As against analogue of this prefix from the assembler the repeated value
to conclude in brackets it is impossible.


                        Call of procedures in C-style.
		       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    That it was possible to make calls of procedures in C-style in 0.212
versions The prefix of the name of the c_ procedure was entered, on which the
compiler defined, that this procedure should be perceived as the procedure in
C-style. On that moment such the way of definition such as procedure call was
more simplis and optimal. Now, when in the compiler the mechanism of the
declaration of procedures has appeared, has become Possible to approach
syntax to standard C.

    In this version the prefix c_ is cancelled. It the function now executes
the modifier cdecl. If you use the procedure in C-style earlier than she is
defined, this procedure should be declared earlier than she will be is used.
If the procedure will be defined before it of application, it to declare
unessentially. The declaration of the procedure has the following syntax:

rettype modif procname ();

    First goes the unessential type of return from procedures. By default it
for 16-bit programs word, and for 32-bit dword is equal. Then should go also
the unessential modifier. By default all push-down procedures in with - (for
by exception of a mode of compilation of programs under Windows, where by
default the style of call of procedures stdcall operates) have style pascal.
Now C-- supports only one modifier - cdecl, which can change style call of
procedures from by default in C-style. Further there is a name of the
procedure with by brackets, which are tag that that you declare the
procedure, instead of variable. Completes the declaration character a
semicolon.

    At the declaration of procedures in C-- to register parameters of the
procedure unessentially (the compiler does not inspect yet number and type,
of transmitted, parameters), but if you will insert them it there will be no
error, a compiler them simpl will ignore.
Return to list version.





0.217 from 24.05.99

                              32-bit code.
			     ~~~~~~~~~~~~~

    In this version of the compiler the possibility has appeared to create
32-bit programs under DOS and Windows. The 32-bit code has the features both
the requirements. For an explanation them I can to you advise to esteem the
appropriate literature. Because of these features practically almost all
procedures from available libraries, and procedure, taking place in the file,
dynamic libraries all is absolute (as they are compiled in 16-bit Mode), will
not work in a 32-bit mode. Probabl, it is necessary hard work in creation of
new 32-bit libraries. But under Windows at you the access to a huge amount of
API-procedures has appeared.


    The 32-bit code for DOS.
    ~~~~~~~~~~~~~~~~~~~~~~~~

    To compile the 32-bit program for DOS it is necessary to start the
compiler with a key of the /d32 command line. But operation of the 32-bit
program for DOS is impossible without the expander DOS. For C-- WDOSX was
selected. Full a package this expander DOS it is possible to take in internet
on http://www.geocities.com/SiliconValley/Park/4493. To us from this package
the wdosx.dx file will be necessary only. That the compiler knew where to
search for this file both it the name, is necessary in the c--.ini file to
register line stub=path_name_to_stub_file.  Example:

    stub=c:\c--\wdosx.dx

    If not to add in c--.ini this line, the compiler will generate The 32-bit
exe-file, but without the expander DOS. That to this file to link the
expander DOS is necessary to take from a package WDOSX the stubit.exe file
and to start it, by specifying it as the parameter a name of the compiled
file. If you have added in the c--.ini file line from a variable stub, the
compiler will create to you available to the use the file. If in the command
line together with a key /d32 to specify and key /ns, the line from a
variable stub from the c--.ini file will be is cancelled, and you receive the
file without the expander DOS.

    For the 32-bit DOS-file it is possible to use the instructions of the
compiler ?parsecommandline TRUE/FALSE or it extended variant ?argc
TRUE/FALSE. The support of the instruction is realized also ?atexit
TRUE/FALSE. The instruction ?initallvar by the compiler is installed in a
state TRUE. At all install this instruction in FALSE. Differently your
program will not work.


    The 32-bit code for Windows.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    To compile the program, written for Windows is necessary to start the
compiler with a key of the /w32 command line. Then it is necessary to compile
the file of resources (if it is necessary and exists). About that both to
write the file of resources to me it is necessary to send you again to,
appropriate, to the literature. For compilation of resources I used the
compiler of resources from BC. The following files from a package BC v5.0
will be necessary for this compilation for you:

  BRC32. EXE
  BRCC32. EXE
  TLINK32. EXE
  RW32CORE.DLL
  RLINK32. DLL

    If you in the program use calls of API-procedures, these the procedures
should previously necessarily be declared. The declaration of procedures has
the following form:

extern WINAPI "DLL_name"
{
    returncode procname1
    returncode procname2
    procname3
}

  Where:
       DLL_name - name and extension of the dll-library in which there are
                  these procedures.
     returncode - type of return from api-procedures. By default it is equal
                  dword.

    Basically it is possible and it is necessary to create the file, in which
will be described all frequently used API-procedures. But to take a great
interest in it does not cost, as everyone the declaration of the
API-procedure requires some of memory, and with it at the compiler recently
of steel to occur complexities.

    The calls of API-procedures very much frequently use as parameters
constants. These constants are described in files winuser.h-- wingdi.h-- etc.
from a package BC 5.0. It will be necessary these constants to copy on C--.
But again does not cost strongly to take a great interest in it.

    The programs written under Windows, have one important feature - all
parameters in push-down procedures are transferred in the return order (so
the called C-style), but clearing of the stack of parameters occurs in
procedures. The original hybrid C and pascal of styles turns out. It is not
my invention - such requirement for calls of api-procedures.

    In C-- there are some limitations at writing programs for Windows. It:
1. The size of the code and data should not exceed 64 kilobytes.
2. C-- does not know how to not export yet procedure.
3. The support of the startup-code is not realized yet.


    The conclusion.
    ~~~~~~~~~~~~~~~

    Probably, it is better than my explanations to you will help to clear up
with all by it the examples, which go together with this version of the
compiler.

    In the compiler the instruction also has appeared ?code32 TRUE/FALSE,
which permits/prohibits generation of the 32-bit code. With the help of this
instruction it is possible to receive and 32-bit com-file. But as then it
will be possible to use this the file I do not know. If you have any ideas on
application of 32-bit The com-file, inform me. To use this instruction
without special needs I do not advise you.
Return to list version.





0.216 from 21.04.99

                 Compilation of the code of expanders ROM-BIOS.
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Expanders ROM-BIOS (BIOS of videocontrollers, network cards...) have
defined structure and requirements. C-- now can facilitate to you the process
creations of the ROM-BIOS code. If to start the compiler on compilation with
a key /ROM command lines, the compiler will create a signature (header)
ROM-BIOS, will fill in the stayed free place up to the indicated size ROM by
the code fillings, will count up and ROM will correct the check total.
    For this mode of compilation there are some specific instructions:
  1. ?sizerom value - this instruction communicates to the compiler the size
ROM in Bytes. If this instruction is not indicated, the compiler itself will
select minimum the suitable size ROM from a number: 1024, 2048, 4096, 8192,
16384, 32762 or 65536. Free from the code and data a place up to the end of
the size ROM will be filled in byte of filling defined by the instruction?
Aligner. By default it is equal to zero, for ROM of a type 27ååå this byte
can be made equal 0xFF. Last byte ROM will be corrected by the compiler so
that the check total was equalled to zero.
  2. ?Movedatarom TRUE/FALSE - this instruction communicates to the
compiler whether is necessity to copy data from ROM in the RAM. By default
it is placed in FALSE. If this instruction to define TRUE, the compiler
will insert into area initialization the code moving data from ROM in the
RAM. Thus the register DS will be is placed on a segment of the RAM. The
stack also will be rearranged on this segment. Thus main procedure will
receive handle with the registers AX = ES = DS = SS = to a segment of the
RAM with the data, transferred in it. If this instruction to place in
FALSE, the register DS will be all the same rearranged on the address
segment of the RAM, as your code will use this segment for non-initialized
global variables. Initialized variable Will stay in ROM and all calls to
them will be made through the register CS. As remain not touched (such with
what it has placed) main BIOS) and stack.
  3.?dataseg value - this instruction to the compiler communicates the
segment address the RAM, which can be used by your code. By default it is
equal 0x70. This address you can learn(find out) at any moment áç¨â ¢ it
from your code on to offset 4. For example: DS = CSWORD [4]; some remarks:
  1. Do not overlook, that at the moment of initialization ROM-BIOS DOS is
not loaded yet and accordingly all procedures using calls DOS to work will
not be.
  2. It is impossible to complete operation of the program by procedures
ABORT() or EXIT() and them similar. The operation of the expander ROM-BIOS
should be completed only by output from main() procedures.
  3. If the instruction ?movedatarom is placed FALSE, be close() at
operation with the initialized variables. They in this mode are availablis
only for reading, also are addressed through the register CS.


               Output file *.EXE with memory model tiny.
	      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Actually code of the *.exe file of a model tiny by nothing differs from
the *.com code. In effect it is the same com-file to which is added 32-bytes
header the exe-file. The unique difference arises when you compile the file
with by the instruction ?resize TRUE. In the com-file under this instruction
in the code of the program the appropriate code changing size of availablis
memory is added. In the exe-file for these objectives the header of the
exe-file will be corrected. That to receive the exe-file with memory model
tiny, it is necessary to start the compiler with a key in to the /TEXE
command line.


                                 Pointers.
				~~~~~~~~~~~

    In this version the attempt is made to learn C-- to work with the
pointers. Once again I shall repeat, that it only attempt, and therefore
pointers are realized yet in full size and, probably, in some cases will be
generated the incorrect code. But if you will help me, I hope to us it will
be possible to learn it to work with the pointers. Your help can consist in
revealing situations at which the incorrect code and sentence of variants is
generated the code, which can be generated on various variants of syntax.
    Example of application of the pointers in C -:

char *string[4]={"string1", "string2", "string3", 0}; // a pointer array
char *str="string4";

main ()
int i;
char *tstr;
{
	 FOR (i = 0; string [i]! = 0; i ++) {
		 WRITESTR (string [i]);
		 WRITELN ();
	}
	 FOR (tstr = str; byte *tstr! = 0; tstr ++) {
		 WRITE (byte *tstr);
	}
}


            Calculation in the registers EAX/AX/AL with is familiar.
	   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Earlier all calculations in the registers were made as with unsigned by
values. For example:

  int a, b, c;
  AX = a * b / c;

    Thus the compiler generated unsigned of the instruction div and mul, as
the registers are considered unsigned as variables. Now if to write so:

  AX = int a * b / c;

that now compiler will generate the instructions idiv and imul.
    I pay your attention, that for the register AL it is possible to use only
the modifier char, for AX accordingly only int, and for EAX - long. For other
registers similar cannot be done.


                  Corrected errors of the previous versions.
		 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1. Instruction ?setdinproc did not insert dynamic procedures from the
library Dynamic procedures.
    2. At generation of the code of assignment of contents of the registers
AL/AX/EAX in spot of memory defined low neat the incorrect address
was generated this spot.
    3. At calculation of expressions with a floating point, if arose
necessity to transform number of a format float to an integer, compiler not
always automatically inserted into the code procedure call of converting
float2numer().
    4. At calculation of a value of a type byte or char, if among operations
of calculation there was a division, the compiler sometimes generate the
incorrect code - before operation of division was not done zero of the
register AH (or extension the AL sign in AH for a type char).
Return to list version.





0.215 from 14.03.99

                  Conditionals MINUSFLAG and PLUSFLAG.
		 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    For check of bit of the sign in the register of flags in the compiler
are entered two the special conditionals - MINUSFLAG and PLUSFLAG.
Expression MINUSFALG Accepts value 'is true' if bit SF (flag of the sign)
register of flags is placed in 1. The expression PLUSFLAG accepts value 'is
true' if bit SF ( the flag of the sign) register of flags is placed in 0.
Examples:

1).
    i = A + b;
    IF (MINUSFLAG) i = 0; // if i negatively - to place it in 0

2).
    do {
      i - = a;
   } while (PLUSFLAG); // a cycle while the variable i is positive


                        Declaration of procedures.
		       ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The declaration of procedures is entered to communicate to the compiler
about the type return from procedures. If the procedure has the type of
return void or word or not participates in operations of matching or
assignment, such procedure it is possible not to declare.


                Change such as expression at assignment.
	       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    As is known, in C-- at calculation of a value all variable
participating during calculation (i.e., taking place to the right of the
sign, the equalities) will be transformed to the type of a calculated
variable. Now if the ambassador the sign of equality to write the type
distinct from such as a calculated variable, all variable participating
during calculation, will be transformed to this to the new type, and only
finite result will be transformed to the type, of calculated, by variable.
an example:

int i, a;
long b;
char c;

  i = a * b + c;

    The values of variables a, b, and c in this example before calculation
will be are transformed to the int type (variable type i). But if to write
down this expression here so:

  i = long a * b + c;

    That the variables a, b, and c in this example before calculation will
be are transformed to the long type, and the finite result will be
transformed to the type by variable i - int.


                             Other changes.
			    ~~~~~~~~~~~~~~~~

    From the compiler the support of keys of the /MACRO /PROC /REGPROC
command line is removed, as in them has disappeared necessity.

    In some situations at compilation there is a stack overflow, in links
with it in this version of the compiler the size of the stack is increased
twice.  Now it is equal 8192 bytes.

    In the library some procedures are added:

long filelength (word handle) - returns length of the file (as against
         procedures FILELENGTH and FILELENGTH32 a situation of the pointer
	 of the file not varies).

long lseek (word handle; long offset; byte mode) - installs the pointer
	 file in the given position. As against similar procedures FSEEK
	 and LSEEK the new position of the pointer is transferred as one
	 the variable of a type long (passs necessity to divide offset On
	 two components).

long tell (word handle) - returns a current rule of the pointer of the file.

long ATOL (, strofs) - will transform string to number of a type long.

void BYTE2STRBIT (val, strbuf) - will transform byte to a bit string (zero
	 and Units). The variable strbuf should contain the address of the
	 buffer for string by the size not less than 9 bytes.
Return to list version.




0.214 from 18.02.99

                      Library of dynamic procedures.
		     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version of the compiler the support of the library of dynamic
is added procedures. Now compiler can work only with one library, of
having, the name MAINLIB and having the LDP extension (Library Dynamic
Procedures). The library should be in one directory with the compiler.

    You ask - what advantages this library, in comparison with gives by
traditional mode of work?
    In first the necessity passs to write numerous includes (I do not know
As you, and me it irritates) slightly.
    In second, theoretically, the compile time of programs (I should
decrease did not check, but whom interestingly check up).
    Well and in third, the loading of the processor and necessity of the
compiler decreases in resources.

    In the library all internal procedures are transferred almost. Are left
only macro for operation with ports, procedure for operation with the
command line PARAMCOUNT, PARAMSTR and procedures of termination ABORT,
EXIT. In the compiler the support of the ATEXIT procedure is added. In the
library are added almost all dynamic procedures from files *.h--. For today
the library contains 431 procedure. For operation with the library the
CMMLIB.EXE utility is written. The utility allows to receive listing all
procedures, to add and to delete procedures.
    The procedures are added to the compiled file after the termination it
compilations, therefore in a compile time the compiler can not know the
type return from procedures (as you know in C-- the declarations are not
realized procedures). It sometimes can result in incorrect results.
    For example:
    In the library there is a GETVIDEOMODE procedure which has the type of
    return byte. But on line IF(GETVIDEOMODE() == 0x54)... The compiler
    generate matching the register AX (by default the compiler considers,
    that the procedure has at return the word type). In such case it is
    necessary or obviously to specify the type of return Procedures -
    IF(byte GETVIDEOMODE() == 0x54)... or before use by this procedures to
    make it the declaration - installation by a line byte GETVIDEOMODE();.
    Also, if it is the register procedure, it is possible to use it as
    macro: IF(@GETVIDEOMODE() == 0x54)... Then the compiler will be forced
    to get from the library this procedure and by that learns it a return
    code.


                         Support of the ATEXIT procedure.
			~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The ATEXIT procedure registers the procedure which address is
transferred to the ATEXIT procedure as the parameter, as the procedure of
completion of the program. This procedure will be called at the moment of
completion of the program by procedures ABORT or EXIT or instruction RET
from main.
    In total it is possible to register up to 16 procedures. The procedures
are called in the order a converse to the order of their registration.
    The support of the ATEXIT procedure is included by the instruction to
the compiler ?atexit.
Return to list version.





0.213 from 1.02.99

              Character '$' in the assembly instructions.
	     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Now in the assembly instructions, as well as in the assembler, it is
possible to use character '$'. At compilation this character will be
replaced on, current, value of the register IP. It can be used at
calculation of numerical values depending on a current address, but
character '$' it is possible to use in them unitary and it should be first.
An example:

  $ JMP SHORT $+2 // to transfer handle to the following command
  $ DW $ 	  // to write down in a word a current address


                       Macro of operation with ports.
		      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In the compiler the support macro is added: inp(), inpotr(), inportb(),
inportd(), outp(), outport(), outportb(), outportd(). They should become by
alternative of the PORT.H-- library also will allow to receive faster and
the compact code.

Syntax:
    byte inp (potr)      - to consider one byte from a port
    byte inportb (port)  - to consider one byte from a port
    word inport (port)   - to consider a word from a port
    dword inportd (port) - to consider a double word from a port
	 port - the word with the address of a port is the unessential
                parameter. If it the value is not given, the command will
		be generated in al,dx. If the port value will be less
		than 256, will be the in al,port command is generated.
    outp (byte val, word port)      - to write down byte in a port
    outportb (byte val, word port)  - to write down byte in a port
    outport (word val, word port)   - to write down a word in a port
    outportd (dword val, word port) - to write down a double word in a port
	 val - written value
	 port - the word with the address of a port is the unessential
	        parameter. If it the value is not given, the command will
		be generated out dx,al. If the port value will be less
		than 256, will be The out port,al command is generated.


                Alternate handler of the command line.
	       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Alternate of this handler of the command line consists in that, that at
call PARAMSTR(0); you receive the address of string in which the path both
is indicated name of the started program. The alternate handler of the
command line is included by the instruction ?argc TRUE or from the command
line of the compiler by a key /+argc or line +argc in file C--.INI.


               Instruction the managers by placement of variables.
	      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version the number of the instructions allowing is added to
operate layout the unassigned variables. Earlier all unassigned variables
settled down outside the file.
    Now by instruction ?initallvar TRUE the mode is included at which by
all to the unassigned variables the zero value will be assigned and they
will be to settle down in that place where were declared. The FALSE
parameter of this instruction Disconnects this mode.
    The instruction ?usestartup permits to the compiler to use spots of the
code initial initialization of the program for the consequent placement in
them the unassigned variables.
    By the instruction ?startusevar it is possible to specify the initial
address with which the compiler will arrange memory for the unassigned
variables. For example by receiving the instruction ?startusevar 0x53 the
compiler will have the unassigned variables since 0x53 addresses.


             Change in operation of the instructions? ifdef/ifndef.
	    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Earlier instruction ?ifdef worked on presence of a constant
irrespective of values of its value, and constant ?ifndef worked on absence
of a constant In the compiled file. Now ?indef works only on a constant,
having, the TRUE value, and ?ifndef works as on absence of a constant in
the compiled file, and on a constant important FALSE.
    For the instructions ?ifdef/?ifndef the constants codesize and speed
are reserved, which accept value TRUE or FALSE depending on a mode
optimization. It will be useful to creation of more floppy libraries.
Return to list version.





0.212 from 7.12.98

                                 Structure.
				~~~~~~~~~~~~

    The structure allows to unit in one object a collection of values,
Which can have various types.

Syntax:
~~~~~~~~
struct [tag] {list-elements} declarative [, declarative...];
struct tag declarative [, declarative];
    The declaration of structure begins with the struct key word and has two
the forms of record.
    In the first form types and the names of units of structure are
specified in the list the declarations of units. Unessential in this case
'tag' are the identifier, which names the structural type, defined to data
by the list the declarations of units. 'Declarative' specifies or variable
of structural Type, or array of structures of the given type.
    The second syntactical form of the declaration uses a tag of structure
for the references to the structural type defined somewhere in the other
place of the program.
    The list of the declarations of units represents a sequence from one or
more declarations of variables. Each variable, declared in it the list, is
named as a unit of structure.
    The units of structure are remembered in memory consistently in that
order, in which they are declared. Alignment of units inside structure not
Is made. Structure is aligned on the even address if is included alignment.
    Examples of the declarations of structures:

struct test
{
  int a;
  char b[8];
  long c;
} rr, ff[4];

    In this example are declared structure with the rr name and array from
4 structures with by the ff name. To all set of variables the name (tag)
test is assigned. This tag it is possible to use for the declaration of
other structures. For example:

struct test dd;

   Structure with the dd name having a set of units, of described in, here
is declared tag test.

Initialization of structures at the declaration.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    After the declaration of structure it the units can accept arbitrary
Values. What it it was not necessary structures to initialize. To
initialize structures at their declaration it is possible only global. C--
supports some ways of initialization of structures at their declaration:

    1. One value:
       struct test dd = 2;
In this example to all units of structure dd the value 2 is assigned.

    2. Array of values:
       struct test dd = {1,2, 6};
In this example to the first unit of structure dd the value 1 is assigned,
to second - 2, fourth - 6. Missed and no initialization to values 0 values
will be assigned.

    3. FROM command:
       struct test dd = FROM "file.dat";
In this example on a place where the structure dd is located at compilation
will be contents of the 'file.dat' file are loaded. If the file size is
more than size structures, the superfluous bytes will be loaded in the code
of the program, but they will not be are claimed. If the file size is less
than size of structure,, missing, the bytes of structure will be filled in
zero.

    4. EXTRACT command:
       struct test dd = EXTRACT "file.dat", 24, 10;
In this example on a place where the structure dd is located at compilation
will be the fragment from the 'file.dat' file of length 10 bytes from
offset 24 is loaded. The missing bytes will be filled in zero.

Initialization of structure at execution of the program.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    At execution of the program, except for assignment to each unit of
structure it is possible to initialize values, all structure by assignment
to it of number either by variable. Examples:

void proc()
struct test aa[5],rr;
int i;
{
  aa[0]=0x12345678;
  aa[i]=int 0x12345678;
  aa=long 0x12345678;
  rr=i;

    In the first example memory occupied by the first structure of the
array from 5 structures will be filled in byte 0x78 (by default).
    In the second example memory occupied (i + 1) by structure of the array
from 5 Structures will be filled by a word 0x5678.
    In the third example the memory occupied by all array from 5 structures
will be Is filled by a wide word 0x12345678.
    In the fourth example the memory occupied by structure rr will be
filled By contents of variable i.
    It is possible also to copy contents of one structure in another. For
example:

  rr = aa[2];

    Contents of the third structure of the array of structures aa in
structure will be copied rr.

Operations with units of structures.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    With units of structures it is possible to execute all those
operations, which are availablis for a variable of an appropriate type. For
example:

The structure is declared:
struct test
{
  int a;
  char b[8];
  long c;
} rr[3];
Example of acceptablis syntax:
    rr.a = rr.b[i] * rr[1].c + i ;

The note:
~~~~~~~~~
    At operations with array cells of structures and with, indexed, by
units in which as an index or number of structure is used the variable,
compiler can use the registers SI and DI, and in some situations (for
example: rr[i].b[j] >< rr[i+1].b[j+2]) will be involved both the register
DX.

    It is possible to make it while all - that with structures on C--.


                            Operator sizeof.
			   ~~~~~~~~~~~~~~~~~~

    The operation sizeof defines the size of memory, which corresponds to
the object or type. The operation sizeof has the following sort:

 sizeof (a name of a type)

    Result of operation sizeof is the size of memory in bytes, appropriate
to the given object or type.
    In C-- the operator sizeof is possible to apply to a variable,
registers, types variables, structures, text strings and files.
    If the operation sizeof is applied to the type of structure, by result
Is the size of a tag of the given structure.
    If the operation sizeof is applied to text string, by result operations
is the size of string plus completing zero. For example:

 sizeof ("Test")

Result of this operation will be number 5. However, if you write such
construction:

char a = "Test";

 sizeof (a)

That by result will be 1 - the size such as a variable a. If it is
necessary to have the size of string and to have possibility to manipulate
her, it is possible to recommend such way:

?define RR "Test"
char a = RR;

 sizeof (RR);

Result of this operation will be number 5 - size of string plus,
completing, zero.
    The operation sizeof can be applied and to files. It happens, very
useful at, use of an operator FROM, but can be applied and in other cases.
Example of application of an operator sizeof to files:

 sizeof (file "filename.dat")

Result of this operation will be a file size "filename.dat".


                        Call of procedures in c-style.
		       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Earlier C-- did calls of push-down procedures only in style pascal.
Advantage of this way of call of procedures is the compactness and more the
simple mechanism of generation of the code. To disadvantages, and
accordingly and to advantages of c-style, it is possible to relate hard
affection pascal procedures to number and type of transmitted parameters
(try at call procedures in style pascal to lower one parameter and receive
100 % hangup). I shall remind some technical details of both types of calls
of procedures.

Frame of the stack C-- for close procedures of the stack in style pascal:
     THE ADDRESS
      ...
    BP + FFFE of penultimate byte of local variable
    BP + FFFF last byte of local variable
    BP + 0000 Saved BP
    BP + 0002 RET the address
    BP + 0004 last words of parameters, transmitted to the procedure, (if
              they is)
    BP + 0006 penultimate words of parameters, transmitted to the procedure,
     ...
    BP + nnnn the first word of parameters, transmitted to the procedure,

The release of the stack from the parameters, transferred to the procedure,
occurs directly in to the procedure the RET nnnn command - where nnnn is by
the size, of transferred in, the stack of parameters.

Frame of the stack C-- for close procedures of the stack in style C:
     THE ADDRESS
      ...
    BP + FFFE of penultimate byte of local variable
    BP + FFFF last byte of local variable
    BP + 0000 Saved BP
    BP + 0002 RET the address
    BP + 0004 first word of parameters, transmitted to the procedure, (if
              they is)
    BP + 0006 second word of parameters, transmitted to the procedure,
     ...
    BP + nnnn the last word of parameters, transmitted to the procedure,

    The procedures in style C come to an end by the RET command. Release of
the stack from Parameters occurs in that place procedure whence was called.
Usually it is done by the ADD SP,nnnn command. I.e.  the compiler can
precisely know how many and what parameters you transfer in this case to
procedure and accordingly releases the stack after completion of the
procedure. It is very convenient for procedures, which can process variable
number of parameters (for example procedures type printf).
    What the C-- compiler perceived the push-down procedure as the
procedure in C-style first two character in the name of the procedure
should be: c_. For example:
test(); - the compiler will consider(count) as the procedure in style pascal
c_test(); - already will be the procedure of C-style.


                  Algorithm of search of included files.
		 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version slightly is changed and the algorithm of included files
is extended. For it in the compiler are added: the instruction ?includepath
"filepath", option command lines /ip=filepath and line in c--.ini file
ip=filepath. And it is possible to set some instructions and commands with
paths, but total number looked through paths is limited 16.
    Now search of the included file is made under such scheme: at first the
attempt is done to open the file in the current directory.  If the file
there is not present, attempt further is done to open the file in the
directory by the indicated instruction ?includepath. If the instruction was
not given or file in this directory not has appeared, the attempt is done
to open the file in the directory, of indicated in, to the command line by
the /ip command. If this command was not given or file in the indicated
directory has not appeared, the attempt is done to open the file in
directories indicated in the C--.INI file by the ip command. If this
command was not is given or file in the indicated directory has not
appeared, the attempt is done to open the file in the directory on which
the variable of environment C-- specifies. If The variable of environment
was not given or file in this directory has not appeared, that is done the
last attempt to open the file in the directory whence was started the
compiler.
    The file C--.INI should be in the same directory, where is located the
compiler.
Return to list version.




0.211 from 15.11.98

           Increase of availablis operations in ­¥-EAX/AX/AL expressions.
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Earlier in not-EAX/AX/AL expressions it was possible to use only
operations: additions, subtraction, XOR, OR, AND. Now for CPU 286 or better
it is possible to use multiplying and shifts on number. For example:
     DX = var * CX * 3 * var >> 3;
Will be compiled, and expression
     DX = var * CX * 3 * var >> var;
Will call the message on an error, as in it the shift on a variable (shifts
is indicated it is possible to do only on direct number).
    The note: for 8 bit not-AL of expressions it is possible to multiply
only on numbers:  0, 1, 2, 4, 8, 16, 32, 64 and 128. All these limitations
are connected to tendency to not desroy other registers at use
not-EAX/AX/AL of expressions.


                     Optimization of numerical expressions.
		    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    At inclusion in the command line of an option /ON or in the C--.INI
file of a line ON, The compiler will analyze operations above numbers and
where it probably to reduce number of operations. For example:

line before optimization| After optimization
----------------------------------------------
  AX = var + 7 - 3;     | AX = var + 4;
  AX = var * 2 * 5;     | AX = var * 10;
  AX = var * 2 / 4;     | AX = var / 2;
  AX = var * 10 / 2;    | AX = var * 5;
  AX = var / 2 / 3;     | AX = var / 6;
  AX = var / 4 * 8;     | AX = var * 2;
  AX = var / 16 * 16;   | AX = var;

    Negative consequences. The application of this optimization can have and
    ~~~~~~~~~~~~~~~~~~~~~~ and negative consequences. For example, if it is
necessary to align a value on boundary of the paragraph, you write line:
  var = var / 16 * 16;
But after optimization will be
  var = var;
I.e. the alignment will not be made. It can be avoided, if to
divide this expression on two:
  var = var / 16;
  var = var * 16;
then the optimization will not be made. But for obtaining more compact the
code it will be better to write down so:
    AX = var;
    AX = AX / 16;
    AX = AX * 16;
    var = AX;


          The temporary extension of a digit capacity of a variable.
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    As is known, after multiplying there can be an overflow, the digit
capacity of result can exceed a digit capacity of source operands and There
will be a dist®rtion of result. Partially to decide this problem to you
will help option of the /DE command line or string DE in the C--.INI file.
After the command multiplyings the compiler will look through the rest of
string and if will detect, that the extension of a digit capacity can be
claimed (to claim, extended, digit capacity the operations of division and
calculation of the rest) can, will be accepted measures till it to saving.
For example:

  a=b*c+d/e; //support of the extension of a digit capacity here will be included
  a=b*c+d*e; //here support of the extension of a digit capacity will not be.

    However application of this option can have and negative consequences.
I shall show It on an example:
Let there is an expression
    a = B * c / d;
If values of variables b = 0xC000, c = 0x1000, d = 0x10, after start such
the program will hang up with the message that there was an overflow at
division.


                        Operations with assignment.
		       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Earlier C-- is already skilful to do operations with assignment:
addition +=; subtraction -=; or |=; and &=; xor ^=; shift in left <<= and
shift to the right >>=. Now to them To number two commands - multiplying
with assignment *= and division with were added by assignment.
    Concerning operations with assignment I want to pay your attention,
that at first the expression to the right of the sign of equality will be
calculated, and then will be the operation to the left of him is executed.
At division with assignment will be desroyed the registers EBX/BX/BL and
EDX/DX.
Return to list version.




0.210 from 15.10.98

                  Support of the assembly instructions.
		 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version the implementation of support of the assembly
instructions CPU is completed down to Pentium MMX. Here the list of the
last group of the instructions, of included in this version:

  ARPL r/m16,r16 - correction of the demanded level of the privileges
  LAR r16,r/m16  - to load the rights of access
  LAR r32,r/m32
  LGDT m64       - to load the table of descriptors in GDTR
  LIDT m64       - to load the table of descriptors in IDTR
  LLDT r/m16     - to load the table of descriptors in LDTR
  LMSW r/m16     - to load a word of a state of the machine
  LSL r16,r/m16  - to load a bound of a segment
  LSL r32,r/m32
  LTR r/m64      - to load the register of the task
  SGDT m64       - to remember the table of descriptors in GDTR
  SIDT m64       - to remember the table of descriptors in IDTR
  SLDT r/m16     - to remember the table of descriptors in LDTR
  SMSW r/m16     - to remember a word of a state of the machine
  VERR r/m16     - to check up the selector on access of reading
  VERW r/m16     - to check up the selector on access of record


                      32-bit addressing to memory.
		     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    At last that of C-- was made by shy step to a 32-digit capacity. Now at
addressing it is possible to use the 32-bit registers.  I.e. in reply to
syntax of a type:

      AX = DSWORD [ECX + EDX*2 + 64];
The compiler generate the code, appropriate to it.


                      Warnings at compilation.
		     ~~~~~~~~~~~~~~~~~~~~~~~~~

    Most likely, it is possible to name not warnings, and useful
information at compilation. Now C-- can produce 2 such as warnings: it the
information on autocratic use by the compiler of the registers CPU (except
for the registers AL, AH, AX, EAX) and information on possibility of
application of the short forms language syntax (IF, ELSE, JMP SHORT,
FOR...).
    To permit the output of warnings it is possible with the help of an
option of the command line /+w - then the warnings will be output and from
files, of included in, the compiled file. To permit or to prohibit the
output of warnings only in one file it is possible by the instruction
?warning. The FALSE or TRUE parameter in this the instruction will allow to
permit or to prohibit the output of warnings from, current, the file.
    By default of warning are output on the screen. But if in command line
to add the parameter /wf='file_name' - all warnings will be to be output in
the file 'file_name'.


                    Codeindexing of the array and variables.
		   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In the previous versions there was an attempt to make it, but she has
appeared defective and not always was compiled correctly. Now, like, all
the problems are allowed. As an index the compiler uses the register SI,
and at the command of exchange >< the register DI can also be involved.

    Example:

int buf[20];
int a;
	AX=buf[a];
    The compiler generate the code:
	mov SI,a
	shl SI,1
	mov AX,[#buf+SI]

    As an index all types of variables except for float can be used.
    The application of nested codeindexing is accepted also. For example:

char buf[20];
int a[20];
int b;
	AX=buf[a[b]];
    The compiler generate the code:
	mov SI,b
	shl SI,1
	mov SI,[#a+SI]
	mov AX,[#buf+SI]

Return to list version.



0.209 from 24.09.98

		 Compilation of device drivers.
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In this version the possibility has appeared to receive files of device
drivers. The compiler considerably will facilitate your work at writing
drivers. The compiler Itself will create header of the driver and procedure
the STRATEGY and INTERRUPTION. To you It is necessary only to write the
code of processing of commands.
    What to compile the file of the device driver, it is necessary to add
in the command line a key /SYS. Besides the new instructions to the
compiler have appeared, which operate only with this key. Here they:

   ?sysattribute 'value' - this instruction transfers the compiler
attribute the created driver. By default the value 0x2000 is installed.

   ?sysname 'text string' - this instruction transfers the compiler a name
the future driver. By default the name "NO_NAME" is assigned. Length of the
name not More than 8 characters.

   ?syscommand 'command_0', 'command_1'... 'command_n'; - this instruction
is mandatory. Under this instruction the list of names is transferred to
the compiler procedures of processing of commands of the driver. The names
are divided by commas. The list owes to come to an end in character a
semicolon. It is possible to transfer no more than 25 commands. If any
command has not the code of support, in the list it is necessary to write
down word NONE.

    By default the compiler for the driver does not create the stack. The
driver can to use the system stack. But, speak, that it has small depth. If
your procedures actively use the stack and you do not hope on system, that
by the instruction ?stack 'value' is possible to force the driver to use by
the stack.
    To your procedures of processing of commands by transmission of handle
in the registers ES:BX will be transferred the address of header of
inquiry. The register DS is equal CS. At return of handle your procedures
should save the register DS. In the register AX there should be a return
code. Other registers can be used arbitrarily.
    The procedure of processing of the command of initialization it is
desirable to have last (to have possibility to give back address space,
borrowed, by this procedure to the operating system). Before this
procedure, if you in other procedures of processing of commands use dynamic
procedures, necessarily there should be an instruction ?setdinproc.  about
this instruction more in detail look below. The global variables should be
necessarily initialse.
    As an example I offer you the TIME2000 driver, which on old computers
should help to decide a problem of 2000. In the DRIVER.TXT file you can
find a little useful information on drivers.


		 Instruction? Setdinproc.
		~~~~~~~~~~~~~~~~~~~~~~~~~

    This instruction has appeared to facilitate writing on C-- drivers and
residents. Under this instruction the compiler immediately inserts in the
code of the compiled program all called earlier dynamic procedures. For
curious I shall explain in more detail.
    Usually, the resident programs have such scheme: right at the beginning
is jmp on the code of initialization, which comes to an end by call of
interruption INT 27 with by the address of the latter left resident, byte
(usually it is the address of a beginning the code of initialization).
Between jmp and code of initialization the code settles down Remaining
residently. If you in this code make call of dynamic procedures, at
compilation these procedures will be added in a body of the file in It the
end, behind the code of initialization. If you start such program, that the
code of dynamic procedures will appear outside a resident and first the
call will result in it to hangup.
    If before the code of initialization to put the instruction
?setdinproc, the dynamic procedures will be inserted in this place. As the
C-- compiler is single-pass, do not put this instruction in the beginning
of the file. The compiler can not know, what procedures you are going to
use.
    The global variables at creation of residents and drivers should be
necessarily initialition. For the unassigned variables memory is allocated
outside the file and them waits same to take into account, as dynamic
procedures.


		 Logical association of matchings.
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    At last in C-- the possibility logically has appeared to unite
matchings. I.e. The possibility has appeared to make constructions of a
type:

  IF( (AX > 2) && (CX == 0) || (DX < 8)){...

    It is possible now to do similar constructions as well in cycles
do {} while (), While (), WHILE (), for () and FOR ().

    But do not write off(copy) to be pleased. There are some limitations:
  1. It is possible to unite only up to 30 matchings.
  2. It is impossible with the help of brackets to set priorities at check
     of conditions (as it is made in C). All conditions will be
     checked consistently, in that the order as they are written down.

    Syntactically, each condition should be necessary  made in brackets.


		 Extension of possibilities of cycles for and FOR.
		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Now in cycles for and FOR at a stage of initialization and stage of
increment it is possible to write some commands. A separator between
commands at these stages is comma. For example:

  for ( a=0, b=0, c=1; (a<12) && (c>b); a++, c+=4, b=b*a)

    The number of commands at a stage of initialization is not limited.
Length of string at a stage increments is limited to 1000 characters.

Return to list version.



0.208 from 6.09.98

                          Variables of a type float.
			 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For representation of values with a floating point in the C-- language
the type is entered float. To this type there corresponds a real number of
unary accuracy FPU.
    The format of representation of data with a floating point includes
three fields: the sign, mantissas and order. The sign is defined by a high
significant digit. A field mantissas contains significant bits of number,
and the field of the order contains a degree 2 and the scaling factor for a
mantissa defines.

    31 30..... 23 22........ 0
    |  |       |  |          |
    |  |       |  --------------- - field of a mantissa
    |  -------------------------- - field of the order
    ----------------------------- - bit of the sign

                  Constant with a floating point.
		 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The compiler distinguishes material number from whole on presence in it
of a point. To begin material number owes or digit from 0 up to 9, or the
minus is familiar. Unessential part of material number is the metric of a
degree. The metric of a degree is separated from number of character 'e' or
'E'. Blanks are inadmissible. Here examples of acceptablis syntax:
   0.98
   -15.75
   3.14e2
   1.234567E-20

                   Range of acceptablis values.
		  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The material number of a type float can be in a range from 3.37E38 up
to -3.37E38. The value, close to zero, is minimum 1.17E-38 and -1.17E-38 is
equalled. To write material number of unary accuracy more than 8 digits has
not Sense. The metric of a degree can accept values from + 38 up to -38.

                      Mathematical operations.
		     ~~~~~~~~~~~~~~~~~~~~~~~~~~
    The compiler supports 4 main operations above variables of a type
float: Addition, subtraction, multiplying and division. Is supported also
¨­ªà¥¬¥­â ( var++ - increase on 1), decrement (var-- - decrease on 1),
change of the sign (-var) and exchange by values (var1 >< var2). Other
mathematical operations will be realized in external libraries (in the
fpumath.h-- file some the operations are already realized also I hope, that
you take part in their further Addition). At calculation of a value float
it is possible to use both The variables of other types, they will be
automatically transformed into the float type.
    ATTENTION! The composite mathematical operations are executed in that
order, in which they are written down, despite of rules of arithmetics.

                        Type conversion.
		       ~~~~~~~~~~~~~~~~~
    At mathematical operations which finite total is variable type float,
all operands of other types before calculation will be transformed in the
float type. At assignment of a variable of a type float of a value another
type it also will be transformed into the float type.
    If at integer calculations one of operands will be variable type float,
from it the whole part will be selected, which and start.  involvement in
calculations. At assignment of an integral variable of a value type float,
from it the whole part also will be selected which will be is assigned by
an integral variable.  There is one exception is the 32-bit registers. At
assignment to the 32-bit register of a value type float, the assignment
will take place without converting. For selection of whole parts from a
variable of a type float the float2numer procedure from the file will be
called Fpu.h--.  Therefore, if in the program use variables of a type
float, necessarily add in the program a line - ?include "fpu.h--".
    ATTENTION! If you are going to write the dynamic procedures with by use
of variables of a type float, write them so that did not arise situations,
when the compiler will be forced to convert material number in integral.
Thus the code call of nonexistent will be generated procedures. It is
connected that in C-- is not accepted to make calls of procedures from
dynamic procedures. In a near future I shall try to decide this problem.

                      Operation of matching.
		     ~~~~~~~~~~~~~~~~~~~~~~~
    If at operation of matching the left operand is variable or the
expression of a type float, and right is integral value, the integral value
will be transformed into the material type. If left operand is the integral
expression or variable, and right operand value of a type float, from the
right operand the whole part will be selected, which also start involvement
in matching.
    ATTENTION! At operation of matching with involvement by change of a
type float, Contents of the register AX will be desroyed.

                        About possible bugs...
		       ~~~~~~~~~~~~~~~~~~~~~~~
    The variable of a type float is an innovation in the C-- language and
has not passed yet Full testings. Therefore I admit that the compiler can
generate not the optimal code and sometimes and erroneous. Also, it is
possible, that are still covered not all possible cases of use of this
variable.
    If you have written the program with use of a variable float, and she
works not as it is necessary, or hangs up, and you are sure that the
program is written correctly, send me it sorse with your explanations. I I
shall try to clear up is bug of the compiler or yours. Send also your
sentences on optimization of the code or extension Applications of a
variable float.


                    Instruction to the assumeDSSS compiler.
		   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     Not cnow, whether Peter Cellik (the author of the C-- language) did
not know, whether has overlooked, that at base addressing to memory, when
as base the register is used BP, by default addressing occurs in a segment
SS. Nevertheless compiler at use of push-down variables honesty stamped the
prefix SS. And it is superfluous byte and step at each call to them. To
avoid it was the instruction to the assumeDSSS compiler, which presume that
a segment is thought up data and stack coincide (that in most cases and
occurs) and the compiler not generate the prefix SS.  Now all is put on the
places and necessity for the instruction assumeDSSS has disappeared. In
this version the compiler will swallow this instruction Without warnings
about the unknown instruction, but any operations it will not be to make.

Return to list version.



0.207a from 6.08.98

        List of the supported instructions of the arithmetic coprocessor.
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

F2XM1         Calculation ^b2x-1
FABS          to receive an absolute value
FADD ST,ST(i) add of material numbers
FADD ST(i),ST Addition of material numbers
FADD float    add float with ST(0) results in ST(0).
FADDP ST(i)   add of material numbers and extract from the stack.
FBLD var80    Packed decimal loading (BCD).
FBSTP var80   Record of packed decimal value (BCD) and extract from the stack.
FCHS          Change of the sign.
FCLEX         Clearing of exclusive interruptions.
FNCLEX        Clearing of exclusive interruptions.
FCOM ST(i)    alignments of material numbers in ST (0) and ST(i))
FCOM float    Matching of material numbers in ST (0) and float.
FCOMP ST(i)   alignments of material numbers ST(0) and S(i)) extracts from
              the stack.
FCOMP float   Matching of material numbers ST(0) and float and extract from
              the stack.
FCOMPP        Matching of material numbers and extract from the stack twice.
FCOS          Cosine ST(0) (387 +).
FDECSTP       Decrease of the pointer of the stack.
FDISI         Prohibition of interruption (only for the coprocessor 8087).
FCOMP ST(i)   division of material numbers.
FDIV ST(i),ST Division of material numbers.
FDIV float    Division of material numbers.
FDIVP ST(i)   division of material numbers and extract from the stack.
FDIVR ST,ST(i) division of material numbers with call.
FDIVR ST(i),ST Division of material numbers with call.
FDIVR          float Division of material numbers with call.
FDIVRP         Division of material numbers with call and extract from the
               stack.
FENI           Allowing of interruptions (only for the coprocessor 8087).
FFREE          Release of the register.
FIADD ST(i)    integral addition.
FIADD var32    Integral addition.
FICOM var16    Integral matching.
FICOM var32    Integral matching.
FICOMP var16   Integral matching and extract from the stack.
FICOMP var32   Integral matching and extract from the stack.
FIDIV var16    Division of integers.
FIDIV var16    Division of integers.
FIDIVR var16   Division of integers with call.
FIDIVR var32   Division of integers with call.
FILD var16     Loading whole.
FILD var32     Loading whole.
FIMUL var16    Integer Multiplication.
FIMUL var32    Integer Multiplication.
FINCSTP        Increase of the pointer of the stack.
FINIT          Initialization of the coprocessor.
FNINIT         Initialization of the coprocessor.
FIST var16     Record of the whole value.
FIST var32     Record of the whole value.
FISTP var16    Record of the whole value and extract from the stack.
FISTP var32    Record of the whole value and extract from the stack.
FISUB var16    Integral subtraction.
FISUB var32    Integral subtraction.
FISUBR var16   Integral subtraction with call.
FISUBR var32   Integral subtraction with call.
FLD ST(i)      loading of material value.
FLD float      Loading of material value.
FLDCW var16    Loading of a word of handle.
FLDENV var14b  Loading of a user environment.
FLDLG2         Loading ^blg 2.
FLDLN2         Loading ^bln 2.
FLDL2E         Loading ^blog e.
FLDL2T         Loading ^blog 10.
FLDPI          Loading of number ^bPi.
FLDZ           Loading ^b + 0.0.
FLD1           Loading ^b + 1.0.
FMUL ST,ST(i)  Multiplying of material numbers.
FMUL ST(i),ST  Multiplying of material numbers.
FMUL float     Multiplying of material numbers.
FMULP ST(i)    Multiplying of material numbers and extract from the stack.
FNOP           There is no operation.
FPATAN         Fractional arctangent.
FPREM          the Fractional rest.
FPREM1         the Fractional rest (387 +).
FPTAN          Fractional tanges.
FRNDINT        Roundoff up to whole.
FRSTOR var94b  Restoring of a saved state.
FSAVE var94b   Saving of a state.
FNSAVE var94b  Saving of a state.
FSCALE         Process of scaling.
FSETPM         Installation of a protect mode (287 +).
FSIN           Sine ST(0) (387 +).
FSINCOS        Sine and cosine ST (0) (387 +).
FSQRT          the square Root.
FST ST(i)      Record of material value.
FST float      Record of material value.
FSTCW var16    Record of a word of handle.
FNSTCW var16   Record of a word of handle.
FSTENV var14b  Saving of a user environment.
FNSTENV var14b Saving of a user environment.
FSTP ST(i)     Saving of material value and extract from the stack
FSTP float     Saving of material value and extract from the stack
FSTSW var16    Record of a word of a state.
FNSTSW var16   Record of a word of a state.
FSTSW AX       Record of a word of a state.
FNSTSW AX      Record of a word of a state.
FSUB ST,ST(i)  Subtraction of material values.
FSUB ST(i),ST  Subtraction of material values.
FSUB float     Subtraction of material values.
FSUBP ST(i)    Subtraction of material values and extract from the stack.
FSUBR ST,ST(i) Subtraction of material values with call.
FSUBR ST(i),ST Subtraction of material values with call.
FSUBR float    Subtraction of material values with call.
FSUBRP ST(i)   Subtraction of material values with call and extract from
               the stack.
FTST           Check of a top of stack on + 0.0
FUCOM ST(i)    matching.
FUCOMP ST(i)   matching (387 +).
FUCOMPP ST(i)  matching (387 +).
FWAIT          Waiting.
FXAM           Check of a top of stack.
FXCH ST(i)     Swap of contents of the registers.
FXTRACT        Selection exhibitors and significant part.
FYL2X          ^bY * log2 X.
FYL2XP1        ^bY * log2 (X + 1).

        		 Conditional denotations:
			 ~~~~~~~~~~~~~~~~~~~~~~~~
ST     a Top of stack.
ST(i)  Register of the stack, where i = 0-7.
var32  dword or long a variable of memory.
var16  word or int a variable of memory.
var80  10-bytes a variable of memory.
float  float a variable of memory.
var14b 14-bytes a variable of memory.
var94b 94-bytes a variable of memory.


                           Index of the array.
			  ~~~~~~~~~~~~~~~~~~~~~

    In this version the possibility has appeared to use as an index to file
a variable of types: char, byte, int, word. Thus access to array cells is
carried out depending on a declared type of the array. For example:

?define COUNT 10
int array[COUNT];
int i;

void PROC ()
{
  FOR (i = 0; i < COUNT; i ++) {
// To fill in the array array of zero it was necessary to make so earlier:
    BX = i + i; 	 // access to array cells at use in
			 // quality of an index of the registers or direct
			 // of values is carried out on bytes.
    array [BX] = 0;

// Now it is possible to write down so:
    array [i] = 0; 	 // thus the compiler itself will involve
			 // register BX also will correct it the value in
			 // dependences on dimension of the array.

Return to list version.




0.206 from 5.06.98


                  Why steel to occur these versions C--.

     When year back I have got last version C-- and the author has learned
that refuses support of further development of the compiler, I still hoped,
that he be continue. But the year has passed, and Petr Cellik is silent.

     In the C-- language the inconvenience and incompleteness was felt.  In
the compiler some were detected bugs. And to complain there is nobody.
Therefore was solved turn of a sleeve and itself to correct that it is not
pleasant.

                     Explanations to some my innovations.
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Ini-file
~~~~~~~~~
      Is intended for before putting by default of parameters of the
compiler. The parameters register line by line. Syntax same as in command
to line, but without a carrying on char '/'.

 Operator goto, GOTO
~~~~~~~~~~~~~~~~~~~~
     Syntax:
     Goto 'label';
	.
	.
	.
'label':

  The operator of transition goto transfers handle on 'operator' marcing
'label'. Analogue in the assembler to an operator goto is the jmp near
command. Analogue in the assembler to an operator GOTO is the jmp short
command.

 Cycle while, WHILE
~~~~~~~~~~~~~~~~~~~
     Syntax:
  while (expression)
       operator

  The cycle is executed so long as the value of 'expression' will not
become false. 'expression' in the beginning is calculated. If 'expression'
initially is false, a body operator while is not executed at all and the
handle at once is transferred on the following operator of the program.

  The cycle WHILE is similar to a cycle while, but thus the code on 3 bytes
is generated shorter. The size generated of the code in a cycle WHILE
should be less than 127 Byte.

  Examples:
	 While (i < 20) {
		 WRITEWORD(i))
		 i++;
	}

 WHILE (i < 20) WRITEWORD(i))	 // the cycle or will be infinite or not
                                 // Will be executed never
 Cycle for, FOR
~~~~~~~~~~~~~~~
     Syntax:
  for ([ initial expression ]; [condition]; [ increment ])
    operator

  The cycle for is executed so long as the value of 'condition' will not
become false. If 'condition' initially is false, the body of an operator
for is not executed at all and the handle at once is transferred on
following an operator of the program. 'Initial Expression' and 'increment'
are usually used for initialization and modification Parameters of a cycle.

  First step at execution for is the calculation 'initial expression',
if it is present. Then 'condition' is calculated and the estimation is made
it as follows:

  1) If 'condition' is true, the body of an operator is executed. Then is
calculated 'increment' (if it is), and the process repeats.
  2) If 'condition' is lowered, it the value is accepted for true. In it
case the cycle for represents an infinite cycle, which can be completed nly
on execution in it a body of operators break, goto, return.
  3) If 'condition' is false, the looping for comes to an end also handle
is transferred to the following operator.

  The cycle FOR is similar to a cycle for, but thus the code 3 bytes is
generated shorter. The size generated of the code in a cycle FOR should be
less than 127 bytes.

  Examples:
	 For (i = 0; i < 5; i ++) {
		 WRITESTR ("STRING");
		 WRITEWORD(i))
		 WRITELN ();
	}

 Operator break, BREAK
~~~~~~~~~~~~~~~~~~~~~~~
  The operator 'break' break interrupts execution of operators do-while,
for, while, loop. It can contain only in a body of these operators. Handle
is transferred to an operator following for break by a cycle.

  The operator BREAK is similar break, but thus the code on 1 byte is
generated shorter. The size generated of the code from a place where is
applied BREAK up to the end cycle should be less than 127 bytes.

  Examples:
	 FOR (i = 0;; i ++) {
		 FOR (j = 0; j < WIDTH; j ++) {
			 IF (i == 5) BREAK;
		}
		 IF (i == 10) BREAK;
	}

 Operator continue, CONTINUE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  The operator of continuation continue transfers handle to the following
iteration in cycles do-while, for, while, loop. In cycles do-while, while,
loop, following, the iteration begins with calculation of the conditional.
For a cycle for, following, the iteration begins with calculation of
expression of increment, and then occurs calculation of the conditional.

  The operator CONTINUE is similar continue, but thus the code on 1 is
generated byte is shorter. The size generated of the code from a place
where is applied CONTINUE up to beginnings of iteration should be less than
127 bytes.


 Operator switch
~~~~~~~~~~~~~~~~
Syntax:
switch (expression) {
  case constant:
    operator
	...
  case constant:
    operator
	...
...
  default:
   operator
}

    The operator the switch switch intends for a choice of one of several
alternate paths of execution of the program. The execution begins with
calculation of value of 'expression'. After that the handle is transferred
to one of 'operators' of a body of the switch. Body of the switch contains
constructions: case 'constant':, which syntactically represent labels of
operators. The operator receiving handle, is that operator, value of which
constant coincide with value of 'expression' of the switch. The value of
'constant' should be unique.

    The execution of a body of an operator - switch switch begins with a
selected thus operator and up to the end of a body or proceeds so long as
any operator will not transfer handle for bounds of a body.

    The operator the following behind the default key word, is executed, if
any of constants is not equal to value of 'expression'. If default is
lowered, any operator in a body of the switch is not executed, and the
handle is transferred on an operator the following for switch.

For an exit from a body of the switch the operator of break - break (BREAK)
is usually used.

Example:
switch(i)){
  case 'A':
    WRITE(i))
    i++;
    BREAK;
  case 32:
    WRITE ('_');
    i++;
    BREAK;
  default:
    WRITE ('i');
}

 asm key word
~~~~~~~~~~~~~
  The asm key word is a synonym to $ - prefix of the assembly command.
After a word asm it is possible to write the block of assembly commands.
  Example:
	 asm {
		.
		.
		 Push AX
Labl:
		 Push BX
		 Mov AX, 0x1234
		 Jmp short Labl
		.
		.
		.
	}
  The labels inside the block of assembly commands are allowed.


                    Assembly commands added in C--.
		    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BSF r16,r/m16 Scans an operand - source for first bit equal 1.
BSF r32,r/m32 BSF scans from offbit to high, and BSR in a converse.
BSR r16,r/m16 If 1 is found, ZF is installed and in destention
BSR r32,r/m32 number of found bit is located.

BT r16/r32, imm8             Copies value of indicated bit in a flag of carry
BT r16/r32/m16/m32,r16/r32 CF. In an operand-receiver set checked up
BTC r16/r32,imm8               of bits, in an operand-source - number of a
                               position. BT
BTC r16/r32/m16/m32,r16/r32    simple copies bit, BTC - copies and after that
BTR r16/r32,imm8               inverts value in the receiver, BTR - copies
BTR r16/r32/m16/m32,r16/r32    and after that resets in 0, BTS - copies and
BTS r16/r32,imm8               after that installs in 1 value in an operand
BTS r16/r32/m16/m32,r16/r32    the receiver.

SHLD r/m16,r16,imm8  Shift double (2x16 bit) or (2x32 bit)
SHLD r/m32,r32,imm8  of a word made of two operands. SHLD shifts
SHLD r/m16,r16,cl    to the left, SHRD - to the right. In SHLD the first
                     operand
SHLD r/m32,r32,cl    at the left, second - on the right. In SHRD the first
                     operand
SHRD r/m16,r16,imm8  on the right, second - at the left. The released bits
                     first of
SHRD r/m32,r32,imm8  of an operand are filled in bits of the second operand.
SHRD r/m16,r16,cl    Number of shifts is set or in CL, or 8-bit const
SHRD r/m32,r32,cl    to that.

SETcond r/m8  installs byte indicated as an operand, in 1, if the condition
              has value "true", and in 0 otherwise. The condition is
              checked as a combination of flags according to the table:

------------------------------------------------------------------------
| Mnemonics | flags       |        Description of a condition          |
------------------------------------------------------------------------
| SETO      | OF = 1      | To place, if overflow                      |
| SETNO     | OF = 0      | To place, if not overflow                  |
| SETC      | CF = 1      | To place, if carry                         |
| SETNC     | CF = 0      | To place, if not carry                     |
|SETB/SETNAE| CF = 1      |To place, if is low/not higher& not equally |
|SETAE/SETNB| CF = 0      |To place, if is higher or equally/not below |
| SETE/SETZ | ZF = 1      | To place, if is equal                      |
|SETNE/SETNZ| ZF = 0      | To place, if not is equal                  |
|SETBE/SETNA| CF=1|ZF=1   |To place, if is lower|equally/not is higher |
|SETA/SETNBE| CF=0&ZF=0   |To place, if higher/not is lower&is not equa|
| SETS      | SF = 1      | To place, if sign                          |
| SETNS     | SF = 0      | To place, if not sign                      |
|SETP/SETPE | PF = 1      | To place, if even                          |
|SETNP/SETPO| PF = 0      | To place, if is odd                        |
|SETL/SETNGE| SF!= OF     |To place, if it is less/no more ¬ equally|
|SETGE/SETNL| SF = OF     | To place, if it is more or equal/not less  |
|SETLE/SETNG| ZF=1|SF!=OF | To place, if is less than| equal - no more |
|SETG/SETNLE| ZF=0&SF=OF  |To place, if it is more/not less¬ equally|
------------------------------------------------------------------------

                         Command of the MMX-processor.
			 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    All of MMX the commands, behind exception EMMS, refer and operate on two
operands: a source and target. The first operand - target and second
operand a source. The operand of a target can also be the second source
operand for operation. The command writes result atop of an operand -
target.

    The source operand for all of MMX of commands (except for commands of
data transfer), can be either in memory or in the register MMX. An operand
of a target always in the register MMX. For commands of data transfer, an
operand of a source and target can also be the integral register (for the
MOVD command) or memory (for MOVD and MOVQ of commands).

    If one of operands is the memory or variable to initialize them it is
necessary by the dword type, but do not overlook that MMX the commands use
8 bytes. This shift is connected that C-- the type of variables qword does
not support. An example of use MMX of commands in C--:

dword i[2]; 	 // to reserve 8 bytes under a variable i
int j [4];
main ()
{
	 asm{
		 Movq i, MM1
		 Movq MM0,DSDWORD[0x100] /* in the register MM0 8
                                            bytes will be written down
					    from the 100h address on 107h */
		 Movq MM2,DSDWORD[#j]
		 Emms
	}
}

    The EMMS command should be used in each of the following cases:
 - When the application using the commands from a floating point addresses
to MMXT library/DLL. (Use the EMMS command the end MMX of the code.)
 - When the application using MMX the commands calls library/DLL from a
floating point. (Use the EMMS command before call of the code from a
floating point.)
 - When there was a switching between MMX by the code in the task/string
and other tasks/strings in share operating systems, if not sure, that a lot
MMX of commands will be executed before anyone of FPU by the code.
    If the application contains commands from a floating point and MMX of
the command, follow these principles:
 - To select MMXT the unit and unit of the coprocessor in separate streams
of commands (separate cycles or subroutines) so that they contained only
commands of one type.
 - To not rely on a content of the registers across transitions. When the
state MMX is not required, ®ç¨áâì⥠a state MMX, using the EMMS command.
 - Quit from the units of the code from a floating point with the empty
stack.
EMMS - to release MMXT a state. The EMMS command releases a state MMX. This
       command should be used to clear a state MMX (to release tag - a word
       of the registers for operation from a floating point) in the end MMX
       of the subroutine before call of other subroutines, which can
       execute operations from a floating point.

MOVD mmxreg,mem   - to move 32 Bits, transfers 32 bits of packed data from
MOVD mem,mmxreg     memory in the registers MMX and back, or from the integral
MOVD reg32,mmxreg   registers in the registers MMX and back.
MOVD mmxreg,reg32

MOVQ mmxreg,mmxreg/mem64 - to move 64 Bits, transfers 64 bits, of packed,
			   data from memory in the registers MMX and back,
                           or between the registers MMX.

    PACKED ADDITION And SUBTRACTION. The PADDSB, PADDSW commands, and PADDWD
(packed addition) both PSUBB, PSUBW, and PSUBD (packed subtraction) add or
subtract sign or unsigned data items of a source operand of an operand of a
target in a cyclic mode. These commands support packed bytes packed words,
and packed double words. Commands PADDSB and PADDSW (packed addition with
saturation) both PSUBSB, and PSUBSW (packed subtraction with saturation)
add or subtract sign data items of a source operand to or from sign data
items of an operand of a target and cut result to limitations of a range of
a sign type of data. These commands support packed bytes and packed words.
The PADDUSB and PADDUSW commands (packed addition without the sign with
saturation) both PSUBUSB, and PSUBUSW (packed subtraction without the sign
with saturation) add or subtract data items without the sign of a source
operand to or from data items without the sign of an operand of a target
and cut result to limitations of a range such as data without the sign.
These commands support packed bytes and packed words.
PADDB   - Add with wrap-around
PADDW   - Add with wrap-around
PADDD   - Add with wrap-around
PADDSB  - Add signed with saturation
PADDSW  - Add signed with saturation
PADDUSB - Add unsigned with saturation
PADDUSW - Add unsigned with saturation
PSUBSB  - Subtract signed with saturation
PSUBSW  - Subtract signed with saturation
PSUBUSB - Subtract unsigned with saturation
PSUBUSW - Subtract unsigned with saturation
PSUBB   - Subtract with wrap-around
PSUBW   - Subtract with wrap-around
PSUBD   - Subtract with wrap-around

    PACKED MULTIPLYING. The commands of packed multiplying execute four
multiplyings on pairs of 16-digit sign operands, making the 32-digit
subproducts. The users can select high or low parts everyone 32-digit
result. The PMULHW commands (packed multiplying high) and PMULLW (packed
multiplying low) multiply sign words of operands of a source and target and
write a high or low part result in an operand of a target.
PMULHW - Packed multiplic ation
PMULLW - Packed multiplic ation

    PACKED multiplying/addition. The PMADDWD command (packed multiplying
and addition) calculates product of sign words of operands of a target and
source. Four intermediate 32-digit products are summarized in pairs to make
two 32-digit results.
PMADDWD - Packed multiply add

    COMMANDS of MATCHING. The PCMPEQB, PCMPEQW commands, and PCMPEQD
(packed matching on equality) both PCMPGTB, PCMPGTW, and PCMPGTD (packed
matching for greater than) compare appropriate data items in operands of a
source and target on equality or estimate more than, accordingly. These
commands generate a mask of units or zero, which are written in an operand
of a target. The logical operations can use a mask to select units. It can
be used to execute packed conditional operation of transfer without
branching or set of commands of branching. Any check boxes are not
installed. These commands support packed bytes packed words and packed
double words.
PCMPEQB - Packed compare for equality
PCMPEQW - Packed compare for equality
PCMPEQD - Packed compare for equality
PCMPGTB - Packed compare greater (signed)
PCMPGTW - Packed compare greater (signed)
PCMPGTD - Packed compare greater (signed)

    COMMANDS of CONVERSION. The commands of conversion transform data items
inside a packed type of data. PACKSSWB and PACKSSDW commands (packed with
sign saturation) transforms sign words to sign bytes or sign double words
in sign words, in a mode of sign saturation. The PACKUSWB command (packed
by saturation without the sign) transforms sign words to bytes without the
sign, in a mode of saturation without the sign. PUNPCKHBW, PUNPCKHWD
commands, and PUNPCKHDQ (to unpack high packed data) both PUNPCKLBW,
PUNPCKLWD, and PUNPCKLDQ (to unpack low packed data) transform bytes to
words, word in double words, or double words in four a word.
PACKSSDW - Pack dword to word data (signed with saturation)
PACKSSWB - Pack word to byte data (signed with saturation)
PACKUSWB - Pack word to byte data (unsigned with saturation)
PUNPCKHBW - Unpack high data to next larger type
PUNPCKHDQ - Unpack high data to next larger type
PUNPCKHWD - Unpack high data to next larger type
PUNPCKLBW - Unpack low data to next larger type
PUNPCKLDQ - Unpack low data to next larger type
PUNPCKLWD - Unpack low data to next larger type

    LOGICAL COMMANDS. To the PAND command (digit-by-digit logical AND),
PANDN (digit-by-digit logical and-not), POR (digit-by-digit logical OR),
and PXOR (digit-by-digit logical eliminating OR) execute digit-by-digit
logical operations above 64-digit data.
PAND - Bitwise And
PANDN - Bitwise AndNot
POR - Bitwise Or
PXOR - Bitwise Xor

    COMMANDS of SHIFT. The commands of a cyclic shift to the left, cyclic
shift to the right and arithmetic shift the right, shift each unit on
defined number of bits. The logical left and right shifts also enable to
move a 64-digit field as one block, that helps in conversions such as data
and operations of alignment. The PSLLW and PSLLD commands (packed cyclic
shift to the left) and PSRLW and PSRLD (packed cyclic shift to the right)
execute logical left or right shift, and fill in empty high or low bit
positions of zero. These commands support packed words packed double words,
and four a word. The PSRAW and PSRAD command (packed arithmetic shift to
the right) executes arithmetic shift to the right, copying a sign bit in
empty digit positions on the high end of an operand. This command supports
packed words and packed double words. The second operand in these commands
can be 8 bit numbers.
PSLLD - Packed shift left logical
PSLLQ - Packed shift left logical
PSLLW - Packed shift left logical
PSRAW - Packed shift right arithmetic
PSRAD - Packed shift right arithmetic
PSRLW - Packed shift right logical
PSRLD - Packed shift right logical
PSRLQ - Packed shift right logical

Return to list version.