TURBO Pascal und das Arbeiten mit AdressenTyp Bereich Bytes im Speicher ------- ------------- -------- Byte 0..255 1 Integer -32768..32767 2 Real 1E-38..1E38 6Programierer, die sich z.B. mit den 16 Bit Adressen des Z80 herumschlagen, haben hier ein Problem. So ist die Adresse $FFFF deutlich grösser als die Adresse $0001. Trotzdem fällt der Vergleich mit den Standardroutinen (z.B. X<Y) falsch aus, da in TURBO die Zahl $FFFF als -1 interpretiert wird, die ja tatsächlich <1 ist. Um vorzeichenlose 16 Bit Zahlen richtig vergleichen zu können, kann folgende Funktion eingesetzt werden: function cmpwrd(x,y:integer):integer; Begin if x=y then cmpwrd:=1 else if ((x<y) xor ((x<0) xor (y<0))) then cmpwrd:=0 else cmpwrd:=2; End;Diese Funktion liefert
function wEQ(x,y:integer):boolean; function wNE(x,y:integer):boolean; Begin Begin wEQ:=(cmpwrd(x,y)=1); wNE:=(cmpwrd(x,y)<>1); End; End;Diese beiden Funktionen lassen sich jedoch auch mit den Standardoperatoren programmieren: ires:=wEQ(x,y); entspricht bres:=x=y; ires:=wNE(x,y); entspricht bres:=x<>y;(ires ist eine Integer, bres eine Bool'sche Variable) Bei den anderen Vergleichen benötigt man jedoch neue Funktionen: function wLT(x,y:integer):boolean; function wGT(x,y:integer):boolean; Begin Begin wLT:=(cmpwrd(x,y)=0); wGT:=(cmpwrd(x,y)=2); End; End;und function wLTE(x,y:integer):boolean; function wGTE(x,y:integer):boolean; Begin Begin wLTE:=((cmpwrd(x,y)=0) OR (x=y)); wGTE:=((cmpwrd(x,y)=2) OR (x=y)); End; End;Mit diesen Funktionen lassen sich ohne Probleme Vergleichsoperationen bei vorzeichenlosen 16 Bit Zahlen programmieren. Ein anderes Thema ist die Ausgabe von Integers im Bereich $8000..$FFFF, weil in diesem Bereich alle Zahlen negativ dargestellt werden. Im folgenden stelle ich zwei Funktionen vor, die entweder eine Zahl hexadezimal darstellen, wie es eigentlich bei Arbeiten mit Adressen üblich ist, oder aber den oben genannten Bereich als positive Zahlen. HEXtype HexStr = string[4]; function Hex(val:integer):HexStr; const HexTab : array[0..15] of char='0123456789ABCDEF'; var str : HexStr; i : integer; Begin str:='0000'; for i:=4 downto 1 do begin str[i]:=HexTab[val AND $0F]; val:=val SHR 4; end; Hex:=str; End;Hier wird also ein String aus vier Zeichen mit einer Zahl in Hexdarstellung zurückgegeben. INTEGERUm eine Integer Zahl im Bereich $8000..$FFFF positiv darstellen zu können, muß der Zahlenbereich erweitert werden, in diesem Fall mit einer Real. Folgende Funktion kann das übernehmen:function wrd(x:integer):real; Begin if x<0 then wrd:=65536.0+x else wrd:=x; end;Für die Ausgabe einer solchen Zahl bietet sich dann an: write('Adresse=',wrd:0:0);Nebenbei bemerkt hat TURBO Pascal 3.0 schon lange den Elchtest nicht bestanden. Wer es nicht glaubt, sollte die Funktion wrd wie folgt mal testen
program Elch(input,output); var i : integer; adr : integer; function wrd(x:integer):real; Begin if x<0 then wrd:=65536.0+x else wrd:=x; end; BEGIN adr:=$7fff; for i:=1 to 3 do begin writeln(adr:6,' ist ',wrd(adr):0:0); adr:=succ(adr); end; END.Hier soll also der Übergang $7FFF -> $8000 -> $8001 getestet werden. Erwartet wird folgende Ausgabe: 32767 ist 32767 -32768 ist 32768 -32767 ist 32769Und das passiert: 32767 ist 32767 -32768 istJa, und dann schwieg das Lamm, äh, der Elch. In der Tat liegt hier ein Fehler in der TURBO Run Time Library vor, undzwar exakt und nur für die Wandlung der Integer Zahl $8000 nach Real. (Hier findet sich eine genaue Beschreibung) Abgedruckt in Klubzeitung Nr. 53. Autor: Werner Cirsovius |