Seite 1 von 1
Zwischen Codeabschnitte wählen
Verfasst: 14.06.2008 14:00
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.
Verfasst: 14.06.2008 14:16
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
Gruß
Thomas
Verfasst: 14.06.2008 20:40
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.
Verfasst: 14.06.2008 20:49
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...
Verfasst: 16.06.2008 16:55
von Josef Sniatecki
Wie ist es möglich "GoToEIP()" durch einen ASM-Code zu
ersetzen? (Würde mich nur so mal interessieren)
Verfasst: 17.06.2008 09:10
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
Verfasst: 17.06.2008 10:31
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.