String Array



  • 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...


Anmelden zum Antworten