Zwischen Codeabschnitte wählen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Zwischen Codeabschnitte wählen

Beitrag von Josef Sniatecki »

Hier habe ich einen Code, wie man zwischen mehreren Codeabschnitten
wählen b.z.w. wechseln kann:

Code: Alles auswählen

Global LabelSection_Entries.l=(?LabelSection_End-?LabelSection_Start)/4
Global Label.l
Global Index.l

For Index=0 To 10
  Label=PeekL(?LabelSection_Start+Random(LabelSection_Entries-1)*4)
  GoToEIP(Label)
  
  Label_1:
    Debug "This is label 1."
    Continue
  Label_2:
    Debug "This is label 2."
    Continue
  Label_3:
    Debug "This is label 3."
    Continue
Next

DataSection
  LabelSection_Start:
    Data.l ?Label_1,?Label_2,?Label_3
  LabelSection_End:
EndDataSection
Der Befehl "GoToEIP(Pointer)" aus der OnError-Library setzt den
Programm-Lesekopf auf die angegebene Adresse.
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Mir ist zwar nicht klar, wann man es so lösen muß, was aber nicht heissen
soll, das es dafür keinen Anwendungfall gibt, wo es vorteilhaft sein könnte.

Das 4 würde ich gegen SizeOf(long) austauschen, wir bekommen bald nen
64-Bit Compiler :wink:

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Beitrag von Josef Sniatecki »

Man glaubt es zwar nicht, doch der Code ist schneller als folgender:

Code: Alles auswählen

Global Index.l
Global Label.l

For Index=0 To 10
  Label=Random(2)
  If Label=0
    Debug "This is label 1."
  ElseIf Label=1
    Debug "This is label 2."
  ElseIf Label=2
    Debug "This is label 3."
  EndIf
Next
Desto mehr Labels ich einfüge, desto langsamer wird das Programm; denn
wenn jetzt Label=2 wäre, so müsste das Programm zwei
"If"-Befragungen durchgehen.

Der Code mit dem Befehl "GoToEIP()" setzt das Programm sofort
auf die gewünschte Programmstelle. Dadurch ist die Schnelligkeit des
Programms nicht von der Anzahl der Labels abhängig.
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Das ist es bei Select/Case auch nicht...

allerdings sehe ich durchaus den Vorteil bei deinem Verfahren,
dass man ein Array von Labeln verwenden kann, die man dynamisch ansteuern kann.
sowas ist mit klassischen Bedingungen nur sehr umständlich realisierbar.

...aber man muss auch gut aufpassen was man tut,
so programmiert man ohne Netz und doppelten Boden...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Beitrag von Josef Sniatecki »

Wie ist es möglich "GoToEIP()" durch einen ASM-Code zu
ersetzen? (Würde mich nur so mal interessieren)
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

Josef Sniatecki hat geschrieben:Wie ist es möglich "GoToEIP()" durch einen ASM-Code zu
ersetzen? (Würde mich nur so mal interessieren)
Was Du hier möchtest ist ja eigentlich nur ein Goto bei dem man
eine Variable angeben kann, statt nur ein Label.
Und ein Goto ist bei ASM nur ein Sprung ohne Return, ein JMP.
Mit Rückkehrmöglichkeit nimmt man CALL.

Code: Alles auswählen

addr = ?label_1
!CALL [v_addr] : Call Function/Sub

addr = ?label_2
!JMP  [v_addr] ; Goto addr

End

label_1:
   MessageRequester("Info", "label 1")
   !Ret

label_2:
   MessageRequester("Info", "label 2")
   End
Um EIP indirekt zu setzen, kannst Du auch PUSH und RET kombinieren.

Code: Alles auswählen

addr = ?label

!PUSH [v_addr]
!RET

End

label:
   MessageRequester("Info", "label")
   End
In Deinen obigen Code könntest Du GoToEIP(Label) mit einem
Macro ersetzen.

Code: Alles auswählen

Macro Call(variable)
  !CALL [v_#variable]
EndMacro

Macro GotoVar(variable)
  !JMP [v_#variable]
EndMacro

label = ?label_1
GotoVar(label)
End

label_1:
  MessageRequester("Info", "Label 1")
  End
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

wo wir grad dabei sind...

gibt es eine andere möglichkeit als

Code: Alles auswählen

  LabelSection_Start:
    Data.l ?Label_1,?Label_2,?Label_3
  LabelSection_End:
um eine Reihe Labels in ein Array zu bekommen?
es ist halt doch ein wenig aufwendig, zum erstellungszeitpunkt alle benötigten Labels per Hand in eine extra Data-Section zu schreiben.
Aber ne on-the-flyLösung wird wohl kaum möglich sein, höchstens ein Plugin oder ein Preparser, oder?

...so könnte man nämlich auch die Adressen von per IncludeBinary eingebundenen Sprites
in ein Array bekommen, um das Catchen gleich per Schleife ausführen zu können.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten