String Array
-
GutenAbend schrieb:
@abc.w:
Wie gesagt, ich suche die beste Methode für ASM.
Der letzte Satz ist übrigens sehr hilfreichIch habe Dir die beste Methode gezeigt. Es gibt keine bessere. Zum Schluss hast Du zwei Implementierungen, einmal in einer Hochsprache und einmal in Assembler. Die beiden kannst Du vergleichen - je nach dem, was Du genau vorhast - "Optimize for size" oder "Optimize for speed".
Siehe es auch noch so: Mit dieser Methode sparst Du Zeit und gehst an das Problem objektiv heran und du kannst nachweisen, dass Du etwas verbessert (oder auch verschlechtert) hast.
-
@abc.w:
In C++ hab ich das schon einmal gehabt, an sich der gleiche Ansatz wie der von masm. Hab nur gedacht, dass man das in ASM noch etwas "eleganter" lösen könnte...@masm:
Hab deine Lösung jetzt "übernommen" und modifiziert.
Möchte ich jetzt ungern posten, da der Code einfach durch zahlreiche Experimente ziemlich wild aussieht.
Bin nur etwas von den masm32 Macros abgewichen, dh. ich hab z.B. anstatt "alloc(...)" -> VirtualAlloc bzw HeapAlloc verwendet.
Wenn ich nun die Elemente aus dem dynamischen Array ausgeben will, werden die mir falsch herum ausgegeben, d.h. LIFO.
Kann man natürlich leicht umgehen, aber woran liegt das ?Noch etwas:
Rein von der Performance wäre es doch sinnvoller, einen großen Block zu reservieren (und ggf. später noch vergrößern), anstatt für jedes Element neuen Speicher zu reservieren, oder sehe ich das falsch?
-
GutenAbend schrieb:
Bin nur etwas von den masm32 Macros abgewichen, dh. ich hab z.B. anstatt "alloc(...)" -> VirtualAlloc bzw HeapAlloc verwendet.
Ist richtig so, HeapAlloc sollte man verwenden – alloc() liest sich in Beispiel halt besser
GutenAbend schrieb:
Wenn ich nun die Elemente aus dem dynamischen Array ausgeben will, werden die mir falsch herum ausgegeben, d.h. LIFO.
Kann man natürlich leicht umgehen, aber woran liegt das ?Das liegt daran, wie du die Strings ein- und/oder ausgibst.
GutenAbend schrieb:
Noch etwas:
Rein von der Performance wäre es doch sinnvoller, einen großen Block zu reservieren (und ggf. später noch vergrößern), anstatt für jedes Element neuen Speicher zu reservieren, oder sehe ich das falsch?ja, das ist Sinnvoll und deswegen macht es der Heap-Manager für dich.
-
Hm...alles klar soweit, bis auf die Kleinigkeit mit der verkehrten Ausgabe.
Ich baue das Array doch folgendermaßen zusammen:-Str1
-Str1+Str2
-Str1+Str2+Str3
...Ausgabe:
-[Array]
-[Array+1] <- bzw. + 4
-[Array+2]
...Aber warum ist jetzt die Ausgabe LIFO?
Gruß
-
zeig doch einfach den code.
-
Aber nicht für das ganze Durcheinander erschlagen
.DATA str1 DB "str1",0 str2 DB "str222",0 str3 DB "str3333333",0 .DATA? pStrDyn DD 3 DUP(?) .CODE WinMainCRTStartup PROC LOCAL pStr:DWORD lea ESI, pStrDyn xor EBX, EBX .while EBX < 3 cmp EBX, 1 je Load2 jb Load3 Load1: mov pStr, 0 mov pStr, OFFSET str1 jmp Done Load2: mov pStr, 0 mov pStr, OFFSET str2 jmp Done Load3: mov pStr, 0 mov pStr, OFFSET str3 Done: invoke eStrLen, pStr mov EDX, EAX inc EDX ;push PAGE_EXECUTE_READWRITE ;mov EAX, MEM_COMMIT ;or EAX, MEM_RESERVE ;push EAX ;push EDX ;push 0 ;call VirtualAlloc call GetProcessHeap push EDX push HEAP_ZERO_MEMORY push EAX call HeapAlloc mov EDI, EAX invoke szCopy, pStr, EDI mov DWORD ptr [ESI+EBX*4], EDI inc EBX .endw ;---------------------------------------------- lea ESI, pStrDyn mov EBX, 3 GO: dec EBX push 0 mov EAX, DWORD ptr [ESI+EBX*4] push EAX push EAX push 0 call MessageBoxA cmp EBX, 0 jne GO push 0 call ExitProcess ret WinMainCRTStartup ENDP ...
Das ist es. Wie gesagt, öfters "hin und her geschoben", von daher...
-
Vergleich mal deine Schleifen - der unterschied sollte dir auffallen.
Ganz wichtig: Die Register EAX,ECX und EDX werden durch WinAPI-Funktionen geändert - nur ESI,EDI und EBX bleiben unberührt (Win/Intel ABI). Wenn der Inhalt dieser Register gebraucht wird, musst du sie vor einem API-Aufruf z.B. auf dem Stack oder in einer lokalen Variablen sichern (EDX->Zeile 33-45)
-
Oh verdammt!
Nein sorry, das ist meine "optimierte" Methode. So wird alles korrekt ausgegeben...
Wenn ich diese Schleife "korrigiere", tritt eben dieser falsche Effekt auf...
-
GutenAbend schrieb:
Oh verdammt!
Nein sorry, das ist meine "optimierte" Methode. So wird alles korrekt ausgegeben...
Wenn ich diese Schleife "korrigiere", tritt eben dieser falsche Effekt auf...So lange Du keinen Testcode hast, kannst "optimieren" bis zum Umfallen. Danach kann man den Quellcode ausdrucken und als Klopapier benutzen - ehrlich.
-
Man beachte die
"
Optimiert war das falsche Wort, "korrigiert" wäre richtig.@masm:
Das ist die korrekte Schleife die du meinst. Aber hier tritt eben der Effekt auf, das zu erst das letzte Element ausgegeben wird:... ; alles wie oben ;---------------------------------------------- lea ESI, pStrDyn xor EBX, EBX .while EBX < 3 push 0 mov EAX, DWORD ptr [ESI+EBX*4] push EAX push EAX push 0 call MessageBoxA inc EBX .endw push 0 call ExitProcess ret WinMainCRTStartup ENDP ...
-
cmp EBX, 1 je Load2 jb Load3
-
Wo ist der Smilie, der den Kopf gegen die Wand schlägt?
Danke...