Seite 7 von 7

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mo 14. Apr 2014, 08:29
von Dosenware
@Dirk
warum nicht einfach so?
AL hat genau 16 Möglichkeiten für die verschiedenen Blocktypen und so sparst du dir das Vergleichen.

Code: Alles auswählen

; Sprungtabellle
JUMPTAB DW OFFSET ROUTINE1, OFFSET ROUTINE2, OFFSET ROUTINE3, ...... usw.

SUCH:  and  ax,15               ; löschen der Parameter und von ah
       lea  si,[ax+ax+OFFSET JUMPTAB]
       mov  ax,[si]             ; Sprungadresse
	    call si                  ;Aufruf des Unterprogramms

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mo 14. Apr 2014, 09:06
von freecrac
Dosenware hat geschrieben:@Dirk
warum nicht einfach so?
AL hat genau 16 Möglichkeiten für die verschiedenen Blocktypen und so sparst du dir das Vergleichen.
Ja, das ist dann noch besser.

Code: Alles auswählen

       lea  si,[ax+ax+OFFSET JUMPTAB]
Ups. Kleiner Fehler. Für 16 Bit können nur bx, si, di, bp und sp in [] Klammern als Adressregister verwendet werden, aber ax, cx und dx leider nicht.

Dirk

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mo 14. Apr 2014, 09:11
von Dosenware
Dann halt so:

Code: Alles auswählen

; Sprungtabellle
JUMPTAB DW OFFSET ROUTINE1, OFFSET ROUTINE2, OFFSET ROUTINE3, ...... usw.

SUCH:  mov  bx,ax
       and  bx,15               ; reduzieren von BX auf eine Tetrade
       lea  si,[bx+bx+OFFSET JUMPTAB]
 	   call si                  ;Aufruf des Unterprogramms, [] nötig?

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mo 14. Apr 2014, 10:46
von freecrac
Dosenware hat geschrieben:Dann halt so:

Code: Alles auswählen

; Sprungtabellle
JUMPTAB DW OFFSET ROUTINE1, OFFSET ROUTINE2, OFFSET ROUTINE3, ...... usw.

SUCH:  mov  bx,ax
       and  bx,15               ; reduzieren von BX auf eine Tetrade
       lea  si,[bx+bx+OFFSET JUMPTAB]
 	   call si                  ;Aufruf des Unterprogramms, [] nötig?
Ja genau so ist es erlaubt.

Dirk

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mo 14. Apr 2014, 21:06
von DOSferatu
Genau. Selbst in Hochsprachen sollte man sich - zumindest, wenn es schnell gehen soll oder sehr viele Entscheidungen zu treffen sind, von if- oder case- Kaskaden verabschieden. Ich benutze das zwar auch noch, aber nur in unkritischen Bereichen oder wo es nicht so wichtig ist.
Ansonsten sind Entscheidungstabellen dem einfach vorzuziehen.
Und in Assembler sowieso: Immer Sprungtabellen oder Wertetabellen und diese indiziert auslesen oder indiziert springen.
Anders wäre es mir gar nicht möglich gewesen, den Geschwindigkeitszuwachs, den man durch Assemblerprogrammierung gewinnt, richtig auszunutzen.
Man sollte Assembler nicht wie "Hochsprache, nur mit anderen Befehlen" programmieren - sondern man sollte die Besonderheiten, die Assemblerprogrammierung bietet, entsprechend ausnutzen.

(Gar nicht auszudenken, wenn mein GameSys2 statt Entscheidungstabellen/Sprungtabellen mit kaskadierten, verschachtelten Abfragen arbeiten würde... Das wäre der reine Wahnwitz...)

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Di 26. Apr 2016, 22:39
von zatzen
Hier mein erster Versuch mit einer Sprungtabelle. Und es funktioniert... NICHT...

Code: Alles auswählen

      asm
        jmp @suchen
        @sprungtabelle:
        dw 0                             { 0 }
        dw offset decode_bitstream_asm_1 { 1 }
        dw offset decode_bitstream_asm_2 { 2 }
        dw offset decode_bitstream_asm_3 { 3 }
        dw offset decode_bitstream_asm_4 { 4 }
        dw offset decode_bitstream_asm_5 { 5 }
        dw 0                             { 6 }
        dw 0                             { 7 }
        dw 0                             { 8 }
        dw offset decode_bitstream_asm_1_transp  {  9 }
        dw offset decode_bitstream_asm_2_transp  { 10 }
        dw offset decode_bitstream_asm_3_transp  { 11 }
        dw offset decode_bitstream_asm_4_transp  { 12 }
        dw offset decode_bitstream_asm_5_transp  { 13 }

        @suchen:
        mov al, blocktype { 1 oder 2 ( 2 = transparent) }
        dec al { jetzt 0 oder 1 }
        shl al, 3 { jetzt 0 oder 8 }
        mov bl, bits { 1-5 }
        add bl, al { 1-5 oder 9-13 }
        xor bh, bh
        shl bx, 1
        lea si, [bx+offset @sprungtabelle]
        call si

      end;
Sorry falls ich da grundsätzlich noch was nicht kapiert habe...
Hier ist DOSBox sehr praktisch... Ich hätte wohl allein schon
15 Minuten mit neu booten zugebracht...

Liegt es vielleicht daran, dass es keine eigene Routine ist sondern
als erster Versuch einfach mitten in einer Pascal-Routine steht?
Hmm, hab's mal probiert, das alleine scheint's nicht zu sein.
Wäre praktisch wenn man umfangreicheren ASM Code auch einfach
mitten in Pascal Code reinbringen könnte.

...oder ist hier ein FAR-Call notwendig, und man braucht statt nur einem
Offset jeweils einen ganzen Pointer?

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mi 27. Apr 2016, 17:52
von Dosenware
nur zur Sicherheit:
mach mal:

Code: Alles auswählen

        mov al, blocktype { 1 oder 2 ( 2 = transparent) }
        dec al { jetzt 0 oder 1 }
{###}   and al,1
        shl al, 3 { jetzt 0 oder 8 }
        mov bl, bits { 1-5 }
        add bl, al { 1-5 oder 9-13 }
{###}   cmp al, 13
{###}   jg Dummyunterprogramm
und lege mal auf das dw 0 den Zeiger eines Dummyunterprogramms

halt der übliche debuggingkram...

EDIT: Moment: bits {1-5} meint den dezimalwert 1-5?
dann halt statt dem "and bl,$1F" ein Vergleich obs <=5 ist

Edit 2: oder man lässts gleich ganz raus - wird ja vom cmp eh abgefangen.
- cmp bl,13 korrigiert zu cmp al,13

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mi 27. Apr 2016, 18:22
von zatzen
Vielen Dank schonmal für die Antwort!
Leider funktioniert es immer noch nicht.
Sieht jetzt so aus:

Code: Alles auswählen

procedure dummy;
begin
end;


procedure decode_bitstream; assembler;
asm
        jmp @suchen
        @sprungtabelle:
        dw offset dummy                  { 0 }
        dw offset decode_bitstream_asm_1 { 1 }
        dw offset decode_bitstream_asm_2 { 2 }
        dw offset decode_bitstream_asm_3 { 3 }
        dw offset decode_bitstream_asm_4 { 4 }
        dw offset decode_bitstream_asm_5 { 5 }
        dw offset dummy                  { 6 }
        dw offset dummy                  { 7 }
        dw offset dummy                  { 8 }
        dw offset decode_bitstream_asm_1_transp  {  9 }
        dw offset decode_bitstream_asm_2_transp  { 10 }
        dw offset decode_bitstream_asm_3_transp  { 11 }
        dw offset decode_bitstream_asm_4_transp  { 12 }
        dw offset decode_bitstream_asm_5_transp  { 13 }

        @suchen:
        mov al, blocktype { 1 oder 2 ( 2 = transparent) }
        dec al { jetzt 0 oder 1 }
{###}and al, 1
        shl al, 3 { jetzt 0 oder 8 }
        mov bl, bits { 1-5 }
{###}and bl, 01fh
        add bl, al { 1-5 oder 9-13 }
{###}cmp bl, 13
{###}jg @dummy
        xor bh, bh
        shl bx, 1
        lea si, [bx+offset @sprungtabelle]
        call si
        @dummy:

end;
Einen Sprung in eine Procedure wollte ich nicht machen, daher nur Sprung zu label wenn größer 13...
Ich glaube aber auch nicht, dass das Problem bei den Variablen "blocktype" und "bits" zu suchen ist.
Die sind schon verlässlich in ihren Bereichen, sonst würde das bisherige Programm auch nicht
funktionieren.

Ich glaube da stimmt eher noch etwas nicht mit den Adressen.
SI muss doch den Offset enthalten, der tatsächlich in IP geladen wird, oder?
Was macht LEA... LEA erwartet eine Variable. Diese wäre hier [bx+offset @sprungtabelle]
und somit ein Eintrag aus der Tabelle. Wenn ich soweit schonmal richtig liege.
Somit hätten wir aber in SI nicht den Offset zu einer Procedure, sondern lediglich
den Offset zur Position in der Sprungtabelle...

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mi 27. Apr 2016, 18:45
von Dosenware
siehe meine Edits: cmp bl muss zu cmp al werden
Somit hätten wir aber in SI nicht den Offset zu einer Procedure, sondern lediglich
den Offset zur Position in der Sprungtabelle...
ganz ehrlich: k.a. - ist zu lang her
den Wert in si kannst du doch mal ausgeben, dann bekommst du heraus ob du die Adresse falsch ermittelst - und dann einfach mal herumprobieren...

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Mi 27. Apr 2016, 21:34
von zatzen
Es ist so wie ich vermutet habe. Habe eben ein kleines
Programm zum testen geschrieben.
LEA ermittelt in diesem Fall nur die Offsets der Sprungtabelle
und nicht deren Inhalt. So, aber da ich das nun weiss müsste ja
der Schritt zur Lösung nicht mehr weit sein.

- Ok, ich hab's.
LEA SI, [BX+OFFSET @Sprungtabelle] und danach noch
MOV AX, CS:[SI]
und
CALL AX

Wundert mich ja fast dass man CS einfach so benutzen darf.

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Sa 30. Apr 2016, 00:11
von DOSferatu
zatzen hat geschrieben:Wundert mich ja fast dass man CS einfach so benutzen darf.
Na klar darf man CS benutzen - wieso nicht?
Außerdem benutzt man es hier ja nur LESEND. Und LESEND darf man ja ALLES benutzen.
Vom Auslesen von Speicheradressen gehen diese ja nicht "kaputt".

(Wichtig: Das gilt nicht immer für PORTs. D.h. wenn man Ports ausliest, setzt man diese damit manchmal
automatisch zurück oder auf einen anderen Wert. Ist bei PC recht eindeutig gelöst, kann man nicht verwechseln,
weil Ports ja mit IN gelesen und mit OUT geschrieben werden - nicht mit MOV. Auf manchen Systemen (z.B. C64)
wo die Ports quasi "gleichgeschaltet" mit Speicher sind, um den einfacheren Zugriff zu ermöglichen, also
Portzugriffe wie Speicherzugriffe programmiert werden, muß man da mehr drauf achten.)

Man darf auch schreibend auf Adressen, die im Segment ab CS liegen zugreifen - nur sollte man hier natürlich
wissen, was man tut. Aber dazu wurden ja schließlich Labels erschaffen...

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Sa 30. Apr 2016, 00:30
von zatzen
Was ich heute auch herausgefunden habe: Man kann eine Sprungtabelle als procedure definieren und spart
sich somit den Sprung darüber, abgesehen davon dass diese dann schön abseits vom Code abgelegt ist.
Pascal macht also bei einer reinen assembler procedure zumindest kein einziges Byte davor.

Gibt wohl noch manches zu entdecken in der Weise wie man Assembler programmiert.
Das schöne ist, dass man irgendwie sehr schnell lernt. Und mittlerweile fühle ich mich
damit schon ziemlich genauso wohl wie mit Pascal Code. Wenn nicht sogar stellenweise
wohler wegen der Register, die man benutzen kann ohne sie vorher erst zu definieren.

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: Fr 3. Jun 2016, 23:40
von zatzen
zatzen hat geschrieben: - Ok, ich hab's.
LEA SI, [BX+OFFSET @Sprungtabelle] und danach noch
MOV AX, CS:[SI]
und
CALL AX
Es geht noch direkter, ohne LEA:
MOV AX, CS:[BX + OFFSET Sprungtabelle]
CALL AX


LEA ist ja bekanntlich quasi das gleiche wie OFFSET, nur als Befehl.
LEA brauche ich also nur dann, wenn ich wirklich eine Adresse
in ein Register laden will und damit noch etwas vorhabe.

Re: Variablenbezüge in Assembler innerhalb Pascal

Verfasst: So 5. Jun 2016, 11:51
von DOSferatu
zatzen hat geschrieben: LEA ist ja bekanntlich quasi das gleiche wie OFFSET, nur als Befehl.
LEA brauche ich also nur dann, wenn ich wirklich eine Adresse
in ein Register laden will und damit noch etwas vorhabe.
Ja, LEA nutzt man z.B., wenn zur Zeit des Compilierens nicht bekannt ist, an welchem Offset (zum jeweiligen Segmentstart) sich das "Objekt" befindet.