Hier nochmal was zum Thema Arrays und Bereiche mit LongInts
FindMax findet das Maximum. Parameter 1 ist das erste Element des Arrays oder die Bereichsadresse und Parameter 2 die Anzahl der Elemente (oder Anzahl Longs im Bereich). Rückgabe ist der größte enthaltene Wert.
Code
ASM "FindMax", 2
PUSH EBX
PUSH ECX
PUSH ESI
MOV ESI, PAR1 // Zieladresse
MOV ECX, PAR2 // Größe
MOV EBX, $FFFFFFFF // Minimalwert als Maximum vorgeben
CLD
@@maSchleife:
LODSD // Wert holen
CMP EAX, EBX // mit Maximum vergleichen
JL @@maNOM // wenn kleiner, Sprung
MOV EBX, EAX // neues Maximum notieren
@@maNOM:
LOOP @@maSchleife // wiederholen, bis ECX = 0
MOV EAX, EBX // notiertes Maximum in Ausgaberegister
// gepuschte Register in umgekehrter Reihenfolge wieder holen
POP ESI
POP ECX
POP EBX
ENDASM
Alles anzeigen
FindMaxI ist nahezu identisch. Als dritter Parameter kommt noch die Adresse einer Profanvariablen hinzu. Diese nimmt den Index des gefundenen Maximums auf. Bei Bereichen ist der Wert mit 4 zu multiplizieren, um den Offset im Bereich zu erhalten. Anstelle der Adresse einer Profanvariablen kann auch 0 stehen, dann wird der Index nicht ermittelt.
Code
ASM "FindMaxI", 3
PUSH EBX
PUSH ECX
PUSH EDX
PUSH ESI
PUSH EDI
MOV ESI, PAR1 // Zieladresse
MOV ECX, PAR2 // Größe, immer Anzahl Werte
MOV EDI, PAR3 // Adresse Profan-Variable für gefundenen Index
MOV EDX, ECX // Größe merken
MOV EBX, $FFFFFFFF // Minimalwert als Maximum vorgeben
CLD
@@maSchleifeI:
LODSD // Wert holen
CMP EAX, EBX // mit Maximum vergleichen
JL @@maNOMI // wenn kleiner, Sprung
MOV EBX, EAX // neues Maximum notieren
OR EDI, EDI // Test ob Variablenadresse angegenen
JZ @@maNOMI // wenn 0, Sprung
PUSH EDX // Arraygröße auf Stack retten
SUB EDX, ECX // Aktueller Index = Größe - NichtBearbeitet
MOV [EDI], EDX // Aktueller Index in Profan-Variable schreiben
POP EDX // Arraygröße zurückholen
@@maNOMI:
LOOP @@maSchleifeI // wiederholen, bis ECX = 0
MOV EAX, EBX // notiertes Maximum in Ausgaberegister
// gepuschte Register in umgekehrter Reihenfolge wieder holen
POP EDI
POP ESI
POP EDX
POP ECX
POP EBX
ENDASM
Alles anzeigen
Das Gleiche für den kleinsten Wert
Code
ASM "FindMin", 2
PUSH EBX
PUSH ECX
PUSH ESI
MOV ESI, PAR1 // Zieladresse
MOV ECX, PAR2 // Größe
MOV EBX, $7FFFFFFF // Maximalwert als Minimum vorgeben
CLD
@@miSchleife:
LODSD // Wert holen
CMP EAX, EBX // mit Minimum vergleichen
JG @@miNOM // wenn größer, Sprung
MOV EBX, EAX // Neues Minimum notieren
@@miNOM:
LOOP @@miSchleife // wiederholen bis ECX = 0
MOV EAX, EBX // notiertes Maximum in Ausgaberegister
// gepuschte Register in umgekehrter Reihenfolge wieder holen
POP ESI
POP ECX
POP EBX
ENDASM
Alles anzeigen
Und mit Ermittlung des Index
Code
ASM "FindMinI", 3
PUSH EBX
PUSH ECX
PUSH EDX
PUSH ESI
PUSH EDI
MOV ESI, PAR1 // Zieladresse
MOV ECX, PAR2 // Größe, immer Anzahl Werte
MOV EDI, PAR3 // Adresse Profan-Variable für gefundenen Index
MOV EDX, ECX // Größe merken
MOV EBX, $7FFFFFFF // Maximalwert als Minimum vorgeben
CLD
@@miSchleifeI:
LODSD // Wert holen
CMP EAX, EBX // mit Minimum vergleichen
JG @@miNOMI // wenn größer, Sprung
MOV EBX, EAX // Neues Minimum notieren
OR EDI, EDI // Test ob Variablenadresse angegenen
JZ @@miNOMI // wenn 0, Sprung
PUSH EDX // Arraygröße auf Stack retten
SUB EDX, ECX // Aktueller Index = Größe - NichtBearbeitet
MOV [EDI], EDX // Aktueller Index in Profan-Variable schreiben
POP EDX // Arraygröße zurückholen
@@miNOMI:
LOOP @@miSchleifeI // wiederholen, bis ECX = 0
MOV EAX, EBX // notiertes Maximum in Ausgaberegister
// gepuschte Register in umgekehrter Reihenfolge wieder holen
POP EDI
POP ESI
POP EDX
POP ECX
POP EBX
ENDASM
Alles anzeigen
Und hier ein kleines Demo
Code
Window 800, 840
Declare Int A[50], Wert, Index
Declare Memory Bereich
Dim Bereich, 300
Randomize
WhileLoop 0, 49
Wert = Rnd(9000) - 4500
A[&Loop] = Wert
Long Bereich, &Loop * 4 = Wert
EndWhile
CLS
ASM "FindMaxI", 3
PUSH EBX
PUSH ECX
PUSH EDX
PUSH ESI
PUSH EDI
MOV ESI, PAR1 // Zieladresse
MOV ECX, PAR2 // Größe, immer Anzahl Werte
MOV EDI, PAR3 // Adresse Profan-Variable für gefundenen Index
MOV EDX, ECX // Größe merken
MOV EBX, $FFFFFFFF // Minimalwert als Maximum vorgeben
CLD
@@maSchleifeI:
LODSD // Wert holen
CMP EAX, EBX // mit Maximum vergleichen
JL @@maNOMI // wenn kleiner, Sprung
MOV EBX, EAX // neues Maximum notieren
OR EDI, EDI // Test ob Variablenadresse angegenen
JZ @@maNOMI // wenn 0, Sprung
PUSH EDX // Arraygröße auf Stack retten
SUB EDX, ECX // Aktueller Index = Größe - NichtBearbeitet
MOV [EDI], EDX // Aktueller Index in Profan-Variable schreiben
POP EDX // Arraygröße zurückholen
@@maNOMI:
LOOP @@maSchleifeI // wiederholen, bis ECX = 0
MOV EAX, EBX // notiertes Maximum in Ausgaberegister
// gepuschte Register in umgekehrter Reihenfolge wieder holen
POP EDI
POP ESI
POP EDX
POP ECX
POP EBX
ENDASM
ASM "FindMinI", 3
PUSH EBX
PUSH ECX
PUSH EDX
PUSH ESI
PUSH EDI
MOV ESI, PAR1 // Zieladresse
MOV ECX, PAR2 // Größe, immer Anzahl Werte
MOV EDI, PAR3 // Adresse Profan-Variable für gefundenen Index
MOV EDX, ECX // Größe merken
MOV EBX, $7FFFFFFF // Maximalwert als Minimum vorgeben
CLD
@@miSchleifeI:
LODSD // Wert holen
CMP EAX, EBX // mit Minimum vergleichen
JG @@miNOMI // wenn größer, Sprung
MOV EBX, EAX // Neues Minimum notieren
OR EDI, EDI // Test ob Variablenadresse angegenen
JZ @@miNOMI // wenn 0, Sprung
PUSH EDX // Arraygröße auf Stack retten
SUB EDX, ECX // Aktueller Index = Größe - NichtBearbeitet
MOV [EDI], EDX // Aktueller Index in Profan-Variable schreiben
POP EDX // Arraygröße zurückholen
@@miNOMI:
LOOP @@miSchleifeI // wiederholen, bis ECX = 0
MOV EAX, EBX // notiertes Maximum in Ausgaberegister
// gepuschte Register in umgekehrter Reihenfolge wieder holen
POP EDI
POP ESI
POP EDX
POP ECX
POP EBX
ENDASM
Index = -1
Print "Maximum im Array: " + Str$(FindMaxI(Addr(A[0]), 50, Addr(Index))) + " auf Index: " + Str$(Index)
Index = -1
Print "Maximum im Bereich: " + Str$(FindMaxI(Bereich, 50, Addr(Index))) + " an Adresse: " + Str$(Index * 4)
Index = -1
Print "Minimum im Array: " + Str$(FindMinI(Addr(A[0]), 50, Addr(Index))) + " auf Index: " + Str$(Index)
Index = -1
Print "Minimum im Bereich: " + Str$(FindMinI(Bereich, 50, Addr(Index))) + " an Adresse: " + Str$(Index * 4)
WhileLoop 0,49
Print &Loop, "Array : "; A[&LOOP], "Bereich : "; Long(Bereich, &LOOP * 4)
EndWhile
Print
WaitKey
Dispose Bereich
End
Alles anzeigen
Gruß Volkmar