Peter Gerwinski <peter(a)agnes.dida.physik.uni-essen.de> wrote:
> According to Frank Heckenbach:
> >
> > I declared all eax, ebx, ecx, edx, esi and edi as clobbered. Do I need
more?
> > (ebp? What about segment registers, anyway?)
>
> I think if you include `ebp' you are safe. However you should better
> look up the register usage from a suitable book whenever you invoke a
> certain interrupt. This improves performance.
TAKE CARE!!! If you don't use -fomit-frame-pointer your code DON'T
WORK!!! This because EBP is always used as stack pointer, also if you
declare this as clobbered: then if you modify EBP your local variable
offsets
is WrOnG!!
Btw ES, DS, GS, FS, SS cannot be restored by the compiler. You must do
this
from yourself.....
Cya
PrZ.
--
[<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]
| Codename: PrEdAtOr~Z; Sex: Male; Status: Free coder |
* E-mail: predatorzeta(a)geocities.com *
| URL: http://www.geocities.com/SiliconValley/Vista/6573 |
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]
According to The African Chief:
>
> It seems that one cannot have record fields pre-initialised to
> certain values (or am I missing something?) [...]
True. I agree that initalized record fields would be nice.
(What does The Standard say about this, BTW?)
However you can initialize the whole record, like type constants in BP ...
testing it ... uh - sorry, it does not work in fact! :-(
The following should work:
Var
R: record
foo: Integer;
bar: Char;
end (* R *) value ( foo: 42; bar: 'G' );
or, alternatively
Var
R: record
foo: Integer;
bar: Char;
end (* R *) value ( 42, 'G' );
Thanks for the bug report!
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski(a)uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]
According to Frank Heckenbach:
> According to myself (Peter Gerwinski):
> > Ignoring a function's return value *is* a risky thing, because it
> > switches off an error-checking rule which is important for teaching.
> > [...]
>
> I'd still feel better with a separate switch because I try to avoid pointer
> arithmetic and such things in all but low level or very time critical code,
> but I usually have to ignore some function results.
Perhaps `--ignore-function-return'?
> (Perhaps with function
> overloading, this can be solved cleanly -- could it be possible then to have
> a function and a procedure with the same parameters???)
It would be difficult to implement. Having the separate switch, I think
it's not worth the effort.
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski(a)uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]
According to Frank Heckenbach:
>
> I declared all eax, ebx, ecx, edx, esi and edi as clobbered. Do I need more?
> (ebp? What about segment registers, anyway?)
I think if you include `ebp' you are safe. However you should better
look up the register usage from a suitable book whenever you invoke a
certain interrupt. This improves performance.
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski(a)uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]
Hello, everybody!
I am trying now to summarize our "Integer type" problems and to
propose a solution.
Problem #1: Compatibility to BP.
- Some people want `Word' to have 16 bits, because it has in BP.
- Some other people want `Word' to have the same size as `Integer',
because it has in BP.
- Some people expect `LongInt' to have 32 bits, like in BP.
- Some other people expect `LongInt' to be bigger than `Integer',
like in BP.
Hard to escape!
Problem #2: Data types with known size.
Here everybody seems to agree that they are needed, discussions
are about how they should be named.
- `int8' and `card8'
- `int8' and `word8'
- `Integer ( 8 )' and `Cardinal ( 8 )' and/or `Word ( 8 )'
- `0..$FF' (always)
- `packed 0..$FF'
There is also need for a data type which is guaranteed to be the
largest signed/unsigned Integer type available.
Problem #3: Compatibility to GCC.
In order to access libraries written in GCC, GPC must provide integer
types which are guaranteed to be the same as `long long unsigned int'
etc. in GCC.
- Current implementation:
GPC GCC
ByteInt Byte signed char unsigned char
ShortInt ShortWord short unsigned short
Integer Word int unsigned
LongInt = Comp LongWord long long unsigned long long
Obviously, an equivalent for GCC's `[unsigned] long' is missing. This
is because it's the same as `[unsigned] int'. If we can make sure that
this will always be the case, we can safely leave things like they are
and document them (which I already did: see "info -f gpc -n Integer").
- Some people propose to change `LongInt' to be the same as GCC's `long'.
Advantage: closer to GCC's syntax, and same bit size as BP's `LongInt'.
Disadvantage: `LongInt' would not be longer than `Integer'.
- While we are discussing all this, GPC already has type modifiers:
`__long__ Integer' means the same as `long' in GCC. So there *is* a
mechanism with syntax close to C which guarantees compatibility.
(* If we were Borland, we would probably say now: "On all currently
existing platforms, GCC's `long' is the same as `int', so don't worry
about the missing equivalent for `long'." *)
Discussion of #1: Compatibility to BP.
- GPC is *not* intended to be a drop-in replacement for BP.
Compatibility is desireable as long as we don't have to pay a high
price for it. We want to preserve the "spirit" of BP in GPC, not
its "letters". What we do is to "write BP, as it should have been",
not "rewrite BP, exactly as it is".
- GPC is a 32-bit compiler. Maybe we will extend it to 64 bits, some day,
but we won't restrict it to 16 bits.
That's why `Word' etc. are as they are, and why I think they should
not change.
Discussion of #2: Data types with known size.
I think, Frank is right when he says that we must provide a way to define
them rather than defining everything in GPC.
Separate identifiers for everything are not flexible enough.
Round parentheses are easiest to implement, but their syntax interferes
with Schemata. Square brackets come into mind, but they interfere with
UCSD's "long integers".
While the remaining two possibilities are certainly the most `Pascalish'
ones, they are not 100% clear: What size has `packed $1000..$10FF'?
Although 8 bits would be sufficient, GPC would allocate 13 bits. Outside
of packed arrays and records, they would be rounded to the next unit the
machine can access, usually 8 bits, but it can also be 16 or 32 bits.
Despite of the disadvantage sketched above, I think that `packed 0..$FF'
is the way to go. Authors of libraries are encouraged to define their own
types using this mechanism.
To have `LongestInt' as - currently - a synonym for `LongInt' cannot
hurt. If one day there will be something longer than `LongInt', we
can name it `LongLongInt' (because it might be superseeded again by
`LongLongLongInt'), but `LongestInt' will always remain the longest one.
Discussion of #3: Compatibility to GCC.
I can guarantee that the above GPC <--> GCC compatibility rules for
`ShortInt' etc. will not change. Then the only needed thing is something
which is guaranteed to be the same as `long' in GCC, even if `int' is
not the same as `long'. Since we are aiming towards the top, C's `long'
is just "medium" for us. ;-) Thus I propose the names `MedInt' and
`MedWord'.
Summary and Proposal:
Let all GPC integer types like they are, and add `MedFoo' and
`LongestFoo':
GPC GCC
ByteInt Byte signed char unsigned char
ShortInt ShortWord short unsigned short
Integer Word int unsigned
MedInt MedWord long unsigned long
LongInt = Comp LongWord long long unsigned long long
LongestInt LongestWord long long unsigned long long
where `MedInt' happens to be the same as `Integer' and `MedWord' the
same as `Word' on all platforms currently existing.
Introduce `packed 0..$FF' like discussed above.
Forget about `Integer ( 8 )'. But don't forget about UCSD's
`Integer [ 42 ]' which might be implemented later.
Okay like this? Or better keep `Integer ( 8 )' (or `Integer < 8 >', or
`Integer : 8' like bit-fields in C, or `Integer * 1' like in FORTRAN?)
which shows more explicitly how many bits a type has?
Yours,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski(a)uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]
On Fri, 20 Jun 1997 15:49:30 +0200 Frank Heckenbach <heckenb(a)mi.uni-erlangen.de>
wrote:
>
>The African Chief wrote:
>
>> long longint {now = integer}
>> unsigned long longword {now = word}
>
>The problem with this one is that (at least on the common platforms),
>"long" is the same as "int", and I'd expect (as probably many ex-BP
>programmers do) LongInt to be longer than Integer. In fact, some of my
>programs rely on this.
Yes. But in BP, "integer" is 16-bit and "longint" is 32-bit.
Surely, if your programs rely on "longint" to be bigger than
"integer", they also expect "integer" to be 16-bit? If GCC's
"long" is 32-bit and GPC's "longint" is 64-bit - what does that
say about compatibility of data structures?
>
>> long long comp {now = longint, or comp}
>> unsigned long long compword (now = longword}
>
>Why "Comp"? What does "Comp" mean at all? -- I really don't know,
>perhaps I could look it up in one of the 11 BP books... :-|
>
>However, I don't think "Comp" is reasonable name for any integer
>type, except for BP compatibility ("Comp" = "compatibility type" ;-).
This is from the BPW help file;
"Note: The comp type is a 64-bit integer. It holds only integral
values within the range (-2 63 + 1) to (2 63 - 1)."
>> However, since the above will most likely break a lot of existing
>> code, perhaps GPC should have built-in data types that mean
>> *exactly* the same thing as they mean in GCC
>
>Seems necessary. (I didn't like how C messed up their integer types,
>now we're getting the same problems... :-( -- I hope we find a good
>solution finally!)
So do I. The solution may be to predefine these types in GPC;
"int", "short", "long", "uint", "ulong", "ushort", "longlong",
"dword", etc.
These could be defined to mean exactly the same thing as they
mean in GCC - thus, there will be no need to "translate" them into
Pascal.
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.60 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk
Peter Gerwinski wrote:
> Where do such data types matter? Everywhere where we must set up a record
> type of well-known size and structure, for example when reading a binary
> file created by some other program,
(* Not necessarily by another program. If the file can get big, I'd want to
choose the smallest possible types, anyway. *)
> or when communicating with the operating
> system.
>
> For this reason, the syntax must be compact, and somehow closer to the bare
> metal (assembler) than to the clouds (Modula). That's why I prefer `Word'
> here with respect to `Cardinal'. (* Another reason is that when I read
> `Card', I think of games, not of cardinalship. ;*)
(* And when I read "Word", I think of other things, too... *)
> (Due to the need for
> compactness, I think my "Integer ( 8 )" notation was not the best idea. Or
> perhaps it was, and the programmer can define the below in his own Units?)
> So what about this?
>
> Int8 Word8 = Byte
> Int16 Word16
> Int32 Word32
> Int64 Word64
If everyone can define these types, we don't have to determine it here.
You can declare "Word<n>" in your units, and I'll probably declare
"Card<n>" or perhaps "Cardinal<n>" in mine...
> Once more discussing subranges as an alternative: "True Pascal" does not
> specify the storage size, but valid values for those. So I am no more sure
> whether it is wise to guarantee that their size will always be the minimal
> one. And anyway, they are no true replacement for built-in data types of
> well-defined size because no programmer will write `0..$FF' everytime he
> wants to express that something has 8 bits. He will define his own type
> for this reason: "Type Byte = 0..$FF". (Note that `Byte' is built-in in
> GPC!) If we don't want terrible confusion among future GPC hackers, we
> should provide built-in types for such purposes.
But you can't predefine anything that might be needed by someone. Perhaps
someone needs a type with the range 0..1234 that occupies 2 bytes...
So I'd prefer to have a way to define it by oneself. To me, the "packed"
still seems the most logical thing to do: without "packed", the data are
optimized for speed, with "packed" for size. So it would "only" be
necessary to extend "packed" to any type (and I don't see any inherent
reason why it should apply only to records and arrays).
--
Frank Heckenbach, Erlangen, Germany
heckenb(a)mi.uni-erlangen.de
Turbo Pascal: http://www.mi.uni-erlangen.de/~heckenb/programs.htm
Internet links: http://www.mi.uni-erlangen.de/~heckenb/links.htm
Peter Gerwinski wrote:
> What about `__BORLAND_PASCAL__' and `__DELPHI__' (and `__EXTENDED_PASCAL__'
> and `__STANDARD_PASCAL__' etc. which are of course useless because these
> dialects don't allow conditional defines anyway;-)?
Sounds good! :-)
> Everybody, PLEASE check what GPC can already do and what it cannot BEFORE
> you post to this list. You are confusing possible GPC newcomers! ;-)
Sorry for that! (When I wrote the mail, I was at university, and of course,
they haven't installed gpc there...)-:
> > Perhaps (additionally) a separate switch for those who want to use
> > functions as procedures, but without the "risks" implied by "{$X+}"
> > in other aspects? I guess, most of my units would use such a switch.
>
> Ignoring a function's return value *is* a risky thing, because it
> switches off an error-checking rule which is important for teaching.
> Programmers who want to use this feature usually (should;-) know what
> they are doing, and won't be hit by the other "risky" things. For
> instance: A beginner might unintentionally increment a pointer instead
> of the value pointed to. An expert probably won't - he produces much
> uglier bugs.
No, when I want to produce ugly bugs, I write in C or Asm -- it's so much
easier there... ;-)
I'd still feel better with a separate switch because I try to avoid pointer
arithmetic and such things in all but low level or very time critical code,
but I usually have to ignore some function results. (Perhaps with function
overloading, this can be solved cleanly -- could it be possible then to have
a function and a procedure with the same parameters???)
> > - Is calling the Dos interrupt like I did it ok, or is there a better way
> > (perhaps some DPMI calls
>
> Praxis has shown for me that interrupts which don't pass pointers work
> without any DPMI magic. But take care of clobbered registers!
I declared all eax, ebx, ecx, edx, esi and edi as clobbered. Do I need more?
(ebp? What about segment registers, anyway?)
> > -- perhaps even without any asm, that would be better).
>
> No. This would be *very* system-dependent, so it should not be a GPC
> built-in.
No, not built-in of course! I thought of the __dpmi* functions declared in
dpmi.h (at least with DJGPP). I had hoped someone had already figured out
how to use them in gpc... -- So I tried it myself, it seems to work on my
DJGPP (code below). Could someone please check if the code "looks" ok, and
if it works on an EMX system?
BTW: Chief, I think your version of __dpmi_regs in dpmi.pas (v1.00) has a
little mistake, because a "union" in C is a variant record in Pascal.
I think I found a bug with variant records, namely that gpc allows
duplicate identifiers in different "cases". I think the following program
should either fail to compile (what I'd expect), or write "MaxCard"-1 (but
that would be quite difficult to do in general). It does write -1.
var
x:record
case d:integer of
1:(a:cardinal);
2:(a:integer)
end;
begin
x.d:=2;
x.a:=-1;
x.d:=1;
writeln(x.a)
end.
> > Would it seem reasonable (and feasible) to propagate defines
> > (either all of them, or only those that are specially marked) through
> > .gpi files?
>
> No. Defines are C. We do Pascal.
True. Ok, for now we can help with "-Drandom=RandReal" on the command line,
and later we'll make an overloaded function out of it... :-)
UNIT Rand;
INTERFACE
TYPE
Card8=Byte;
Card16=ShortWord;
Card32=Cardinal;
Card64=LongWord;
Int32=Integer;
VAR RandSeed:Int32 VALUE 0;
FUNCTION Random(Range:Card16):Card16;
FUNCTION RandReal:Real;
PROCEDURE Randomize;
IMPLEMENTATION
{$W-,R-,W+}
PROCEDURE NextRand;
BEGIN
RandSeed:=$8088405*RandSeed+1
END;
FUNCTION Random(Range:Card16):Card16;
BEGIN
NextRand;
Random:=(Card32(RandSeed)*Card64(Range)) DIV $100000000
END;
FUNCTION RandReal:Real;
BEGIN
NextRand;
RandReal:=RandSeed/4294967296.0+0.5
END;
{$IFDEF __DJGPP__}{$DEFINE DOS}{$ENDIF}
{$IFDEF __EMX__}{$DEFINE DOS}{$ENDIF}
{$IFDEF DOS}
TYPE
PDPMIRegs=^TDPMIRegs;
TDPMIRegs=RECORD
CASE (d,x,h) OF
d:(edi,esi,ebp,res,ebx,edx,ecx,eax:Card32);
x:(di,di_hi,si,si_hi,bp,bp_hi,res_lo,res_hi,bx,bx_hi,dx,dx_hi,
cx,cx_hi,ax,ax_hi,flags,es,ds,fs,gs,ip,cs,sp,ss:Card16);
h:(edi_b,esi_b,ebp_b,res_b:ARRAY[0..3] OF Card8;
bl,bh,ebx_b2,ebx_b3,
dl,dh,edx_b2,edx_b3,
cl,ch,ecx_b2,ecx_b3,
al,ah,eax_b2,eax_b3:Card8)
END;
{$W-}
FUNCTION __DPMI_Simulate_Real_Mode_Interrupt(Vector:Integer;VAR Regs:TDPMIRegs):Integer; C;
{$W+}
PROCEDURE Randomize;
VAR
RandSeedLoHi:PACKED RECORD Lo,Hi:Card16 END ABSOLUTE RandSeed;
DPMIRegs:TDPMIRegs;
BEGIN
DPMIRegs.ah:=$2C;
{$X+}
__DPMI_Simulate_Real_Mode_Interrupt($21,DPMIRegs);
{$X-}
RandSeedLoHi.Lo:=DPMIRegs.cx;
RandSeedLoHi.Hi:=DPMIRegs.dx
END;
{$ELSE}
FUNCTION Rand:Integer; C;
PROCEDURE SRand(Seed:Cardinal); C;
FUNCTION GetPID:Integer; C;
PROCEDURE Randomize;
BEGIN
SRand(GetPID);
RandSeed:=Rand
END;
{$ENDIF}
END.
--
Frank Heckenbach, Erlangen, Germany
heckenb(a)mi.uni-erlangen.de
Turbo Pascal: http://www.mi.uni-erlangen.de/~heckenb/programs.htm
Internet links: http://www.mi.uni-erlangen.de/~heckenb/links.htm
On Fri, 20 Jun 1997 01:08:29 +0200 (MET DST) Peter Gerwinski
<peter(a)agnes.dida.physik.uni-essen.de> wrote:
[...]
> Int8 Word8 = Byte
> Int16 Word16
> Int32 Word32
> Int64 Word64
I would vote for this.
[...]
>The other thing we must worry about is compatibility to GNU C, because
>the use of GNU Pascal depends on library written in GNU C. For this reason,
>`ShortInt', `ShortWord', `ByteInt', and `Byte' must stay like they are;
>I think it's quite natural then to have `Word' for an unsigned 32-bit Integer.
>I am not sure whether `int' in GNU C might ever change to be different from
>`long int'. (DOES SOMEBODY KNOW???) If so, our (my;) choice for the meaning
>of `LongInt' and `LongWord' might be subject to change. (Note again that
>I am speaking about types that *are* built-in in GPC with the mentioned
>meanings.)
Frankly speaking, I find the dissimilarities between GPC and GCC
very confusing, and, at times, frustrating. Since GPC depends on
GCC, shouldn't the data structures be the same? For example, "long"
in GCC means "integer" in GPC, but "int" also means "integer".
"Longint" in GPC is not the same as GCC's "long", which would seem
to be the sensible thing - but rather, it is the same as GCC's "long long".
"Word" seems to be 32-bit in GCC (am I right?), but with the cygwin32
port of GPC, "word" sometimes seems to be 16-bit, and sometimes,
32-bit (judging from all my attempts at wading through the thousands
of lines of cygwin32 C headers - again, perhaps I am missing something,
but at least, I get very confused at times).
It very soon becomes a very difficult, or, at best, quite error-prone,
task, to translate these C headers for use with GPC.
In my ideal world, GPC and GCC data types would follow this logical
course;
GCC GPC
int integer
short shortint
word word, cardinal
unsigned int word, cardinal
unsigned short shortword
long longint {now = integer}
unsigned long longword {now = word}
long long comp {now = longint, or comp}
unsigned long long compword (now = longword}
This is perhaps only useful for easier translation of the GCC
headers and therefore may not be a priority - however, I don't
think we will ever stop translating those C headers.
However, since the above will most likely break a lot of existing
code, perhaps GPC should have built-in data types that mean
*exactly* the same thing as they mean in GCC - e.g., "int",
"long", "short", etc (in addition to "integer", "longint", "shortint", etc).
This will certainly help in translating a lot of those .H files.
Any thoughts on these things?
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.60 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk
Hi all,
It seems that one cannot have record fields pre-initialised to
certain values (or am I missing something?) - see the code
below. It would be useful to be able to do this in GPC, otherwise,
it would be hard or impossible to translate many C structures
(some of which are declared with fields initialised certain values)
to Pascal (this makes it impossible to translate the whole of the
cygwin32 structures.h for example). Is it possible to add support
for this to GPC? Thanks! Below is my test program which does
not work ....
program testfoo;
Type foo = record
a : integer value -3; { error here }
b : word value 600; { ditto }
end;
Procedure foobar ( var f : foo );
begin
with f do begin
writeln ( a );
writeln ( b );
end;
end;
Var
bar : foo;
begin
with bar do begin
a := -200;
b := 0;
end;
foobar ( bar );
end.
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.60 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk