Einzelnem Byte Wert zuweisen



  • Hallo,

    ich schreibe (oder versuche) gerade folgende Funktion:

    procedure FSetValue( var Dest; TSize, Count: Integer; Values: array of const );
    asm
    	push	edi
    
      mov		edi, eax				// let edi point to destination
      mov		ebx, 0					// pointer-inc
    
    @@_loop:
    	cmp		ecx, edx							// compare counter with count
      je		@@_exit
      mov		ecx, [ebp+20+ebx]
      mov		[eax], ecx   	// move value to destination
      add		ebx, [ebp+12]					// plus Size
      inc		ecx
      jmp		@@_loop
    
    @@_exit:
    	pop		edi
    end;
    

    Wenn man ein BoolArray beispielsweise hat, mit vier Bools, dann soll man die Prozedur so aufrufen können:

    FSetValue( BoolAr, sizeof(Bool), 4, [true, false, false, true] );

    Das Problem daran ist natürlich, dass ich immer direkt vier Bytes schreibe und dann ist immer gleich alles true ...

    Wie kann ich das richtig lösen?



  • Wie kann ich das richtig lösen?

    Indem man sich schon im Vorfeld ueberlegt, ob ein Element so eines Bool-Arrays nun 1,2 oder 4 Byte gross sein soll und gar nicht erst ein temporaeres Array vom "falschen" Datentyp erzeugt.



  • hellihjb schrieb:

    Indem man sich schon im Vorfeld ueberlegt, ob ein Element so eines Bool-Arrays nun 1,2 oder 4 Byte gross sein soll und gar nicht erst ein temporaeres Array vom "falschen" Datentyp erzeugt.

    Ich erzeuge ja kein Array vom "falschen" Datentyp. Die Angabe der Größe entspricht im Endeffekt immer sizeof(Type). Es muss sich nicht immer um bool`sche Werte handeln.

    Die Frage die ich stellte bezieht sich ja auch eher darauf, wie ich einem einzelnen Byte eine Zuweisung machen kann.



  • FrEEzE2046 schrieb:

    wie ich einem einzelnen Byte eine Zuweisung machen kann.

    mov  [eax], cl
    

    Ich erzeuge ja kein Array vom "falschen" Datentyp. Die Angabe der Größe entspricht im Endeffekt immer sizeof(Type).

    Wenn Ziel- und Quell-Array gleichen Datentyp haben kannst Du auch einfach size*count Bytes per "rep movsb/d" kopieren.



  • hellihjb schrieb:

    Wenn Ziel- und Quell-Array gleichen Datentyp haben kannst Du auch einfach size*count Bytes per "rep movsb/d" kopieren.

    Das will mir nicht so ganz gelingen. Könntest du mir vielleicht auf die Sprünge helfen?

    push	edi
    
    mov	ds, eax		// ds points to destination
    mov	esi, eax
    mov    eax, edx	// Size
    mov	ebx, ecx	// Count
    mul	ebx		// Size * Count
    add	esi, ebx	// increment destination ( + size*count )
    
    mov	edx, [ebp+20]  	// edx points to source
    mov	es, edx		// es ...
    mov	edi, edx
    add	edi, ebx
    
    rep	movsb
    
    pop	edi
    


  • Um die Segmentregister brauchst Du Dich in einer 32Bit-Umgebung nicht zu kuemmern:

    mov    esi, [ebp+20] ; esi: Source
    mov    edi, eax      ; edi: Destination
    imul   ecx, edx      ; ecx: number of bytes= Size * Count
    rep    movsb         ; kopieren
    

    effizienter:

    mov   ecx, eax
      shr   ecx, 2    ; erst in 4er-Schritten kopieren
      jz    rest
      rep   movsd
    
    rest:
      mov   ecx, eax  
      and   ecx, 3    ; dann den Rest
      jz    skip
      rep   movsb
    skip:
    

    Bei grossen Daten ist es sinnvoll Alignment sicherzustellen.


Anmelden zum Antworten