HEX : OP: 66 C, ; \ Praefix zum Umschalten auf 32-Bit-Register \ Lege die unteren n Bits des doppeltgenauen Wertes d in umgekehrter \ Reihenfolge auf den Datenstack und setze die restlichen Bits auf 0 CODE DSTIB ( n d -- d' ) OP: BX POP \ 1 CPU-Takt OP: C1 C, CB C, 10 C, \ 1 CPU-Takt 10 # EBX ROR ; hi/lo > lo/hi CX POP \ 1 CPU-Takt OP: DX DX XOR \ 1 CPU-Takt HERE OP: BX SHR \ 1 CPU-Takt OP: DX RCL \ 1 CPU-Takt CX DEC \ 1 CPU-Takt JNE \ 1 CPU-Takt OP: C1 C, CA C, 10 C, \ 1 CPU-Takt 10 # EDX ROR ; lo/hi > hi/lo OP: DX PUSH \ 1 CPU-Takt NEXT END-CODE \ 70 CPU-Takte bei Umordnung von 16 Bits \ 134 CPU-Takte bei Umordnung von 32 Bits \ (4*n)+6 Takte bei Umordnung von n Bits \ Code-Laenge = 40 Bytes \ Was folgt, ist die von Julian Noble stammende \ 16 Bit-Version (Forthwrite # 113) \ Lege die unteren n Bits des einfachgenauen Wertes n2 in umgekehrter \ Reihenfolge auf den Datenstack und setze die restlichen Bits auf 0 CODE STIB ( n1 n2 -- n2' ) BX POP \ 1 CPU-Takt CX POP \ 1 CPU-Takt DX DX XOR \ 1 CPU-Takt HERE BX SHR \ 1 CPU-Takt DX RCL \ 1 CPU-Takt LOOP \ 6 CPU-Takte DX PUSH \ 1 CPU-Takt NEXT END-CODE \ 132 CPU-Takte bei Umordnung von 16 Bits \ (8*n)+4 Takte bei Umordnung von n Bits \ Umordnung von hoechstens 16 Bits \ Code-Laenge = 25 Bytes \ Das STIB bei Julian Noble verbraucht fast zweimal so viel CPU-Zeit \ wie DSTIB und deckt nur Umordnungen von bis zu 16 Bit Laenge ab. \ Wenn es auf Speicher nicht ankommt, kann die benoetigte Zeit fuer DSTIB \ sogar noch weiter reduziert werden (vergleiche das folgende DSTIB-2). \ Lege die unteren n Bits des doppeltgenauen Wertes d in umgekehrter \ Reihenfolge auf den Datenstack und setze die restlichen Bits auf 0 CODE DSTIB-2 ( n d -- d' ) OP: BX POP \ 1 CPU-Takt Hole d OP: C1 C, CB C, 10 C, \ 1 CPU-Takt 10 # EBX ROR ; lo/hi > hi/lo CX POP \ 1 CPU-Takt Hole n 20 # AX MOV \ 1 CPU-Takt AX = nmax CX AX SUB \ 1 CPU-Takt AX = nmax - n AX DI MOV \ 1 CPU-Takt Aequivalent DI SHL \ 1 CPU-Takt zu AX*6, DI AX ADD \ 1 CPU-Takt aber mit AX SHL \ 1 CPU-Takt weniger Takten. OP: DX DX XOR \ 1 CPU-Takt DX = 0 HERE 7 + # DI MOV \ 1 CPU-Takt Plus 7 Bytes fuer MOV, ADD und JMP. AX DI ADD \ 1 CPU-Takt n Kopien von EBX SHR EDX RCL DI JMP \ 2 CPU-Takte nach dem Sprung noch auszufuehren. HERE \ Zur Bearbeitung von XXX 0C0 ALLOT \ 2*n CPU-Takte 32-mal EBX SHR EDX RCL OP: C1 C, CA C, 10 C, \ 1 CPU-Takt 10 # EDX ROR ; lo/hi > hi/lo OP: DX PUSH \ 1 CPU-Takt NEXT END-CODE \ 48 CPU-Takte bei Umordnung von 16 Bits \ 80 CPU-Takte bei Umordnung von 32 Bits \ (2*n)+16 Takte bei Umordnung von n Bits \ Code-Laenge = 245 Bytes : XXX ( -- ) DUP 0C0 + SWAP DO 66 I C! 0D1 I 1 + C! 0EB I 2 + C! \ EBX SHR 66 I 3 + C! 0D1 I 4 + C! 0D2 I 5 + C! \ EDX RCL 6 +LOOP ; XXX \ Fuelle DSTIB-2 mit 32 Kopien von EBX SHR EDX RCL FORGET XXX \ Beseitige Hilfswort XXX, das nun ueberfluessig ist. \ Man beachte, dass es verheerende Wirkung hat, wenn man n uebermaessig \ gross waehlt! Man versuche es spasseshalber mal mit DECIMAL 33 4 DSTIB-2. \ (Der Aufhaengeschleife entkommt man mit CTRL-ALT-PAUSE!) Andererseits \ wuerden ein paar weitere CPU-Takte genuegen, das Problem gegen derartige \ nicht sinnvolle Eingaben abzusichern. Bei DSTIB oder STIB gibt es das \ Problem nicht. Man müsste dann aber bei uebermaessig grossem n einen Moment \ ueberlegen, um das Ergebnis richtig zu interpretieren. \ Es ist wirklich erstaunlich, wie weit man zur Erreichung des gesteckten \ Zieles gehen kann, obwohl weder ZF noch Turbo-Forth einen 32-Bit-Assembler \ haben. Man stelle sich nur einen einzigen der hier verwendeten \ "Quick-and-dirty-Tricks" in irgendeiner der zahlreichen \ "Mainstream-Sprachen" ausserhalb von Forth vor! \ Julian Nobles STIB benoetigt 25 Bytes. DSTIB (von mir) benoetigt 40 Bytes. \ DSTIB-2 (ebenfalls von mir) benoetigt 245 Bytes. Das ist ein interessantes \ Trade-off-Beispiel von Zeit gegen Speicher. Aber was hat man heutzutage \ nicht alles an Arbeitsspeicher in der Maschine? Einige Hundert Megabyte bis \ zu 4 Gigabyte! Was kuemmert einen da schon der benoetigte Speicher - \ solange das (16-Bit-)Forth-System ueberhaupt dermassen viel Arbeitsspeicher \ verkraften kann. Kann es das? Jawoll, Turbo-Forth, ZF und andere \ 16-Bit-Systeme koennen das sehr wohl! Bereits im Real-Modus unter DOS. \ Siehe [VB]. (Ganz stimmt das nicht. Wo liegt der Haken? Aber das ist eine \ andere Geschichte.;-) \ Zur Vereinfachung des Ausprobierens: \ Binaere Anzeige eines 32-Bit-Wertes in einem 16-Bit-System \ Fuehrende Nullen werden nicht angezeigt! : DB. ( d -- ) BASE @ \ Zahlenbasis aufbewahren 2 BASE ! \ Auf binaer schalten ROT ROT \ Bisherige Basis nach vorn UD. \ 32-Bit-Absolutzahl binaer BASE ! ; \ Basis wiederherstellen