Inline-ASM: Hilfe zu Bit-Count

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
7x7
Beiträge: 591
Registriert: 14.08.2007 15:41
Computerausstattung: ganz toll
Wohnort: Lelbach

Inline-ASM: Hilfe zu Bit-Count

Beitrag von 7x7 »

Hallo Freunde,

bräuchte etwas Assemblerunterstützung. Möchte zwei Quad-Variablen binär UND-Verknüpfen. Als Ergebnis möchte ich die Anzahl Bits wissen, die noch übrig bleiben.

Code: Alles auswählen

z.B.

  01000110
& 00011110
= 00000110

Wert = 6
Anzahl gesetzter Bits = 2 (!)

Das Problem ist noch, dass die Zahlen in Arrays stehen. Muss ich die (vermutlich) erst noch vorher in eine normale Variable kopieren um in Assembler zu verarbeiten?

Der Idealfall sollte -rein gedanklich von mir- so aussehen:

Code: Alles auswählen

Array.q(index1,index2,index3) = %01000110
Array.q(index1,index2,index4) = %00011110

Anzahl=0

; (Pseudoassembler ;-) )
Mov EAX, Array.q(index1,index2,index3) 
Mov ECX, Array.q(index1,index2,index4)
AND EAX, ECX
TEST Anzahl, EAX		; beim Z80 (glaube ich) gab es den Befehl TEST für diesen Zweck 

Debug Anzahl 
Zuletzt geändert von 7x7 am 21.08.2011 17:37, insgesamt 2-mal geändert.
- alles was ich hier im Forum sage/schreibe ist lediglich meine Meinung und keine Tatsachenbehauptung
- unkommentierter Quellcode = unqualifizierter Müll
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Inline-ASM

Beitrag von Thorium »

Das eigentliche Problem daran ist das zählen der Bits. Dafür gibt es erst seid SSE 4.2 eine Instruction bei x86.
Ansonsten ist das Bitzählen ziemlich langsam.

http://gurmeet.net/puzzles/fast-bit-counting-routines/
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
7x7
Beiträge: 591
Registriert: 14.08.2007 15:41
Computerausstattung: ganz toll
Wohnort: Lelbach

Re: Inline-ASM

Beitrag von 7x7 »

Thorium hat geschrieben:Dafür gibt es erst seid SSE 4.2 eine Instruction bei x86.
Mein i7 kann ALLES ausser Hochdeutsch :D
- alles was ich hier im Forum sage/schreibe ist lediglich meine Meinung und keine Tatsachenbehauptung
- unkommentierter Quellcode = unqualifizierter Müll
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Inline-ASM

Beitrag von Thorium »

7x7 hat geschrieben:
Thorium hat geschrieben:Dafür gibt es erst seid SSE 4.2 eine Instruction bei x86.
Mein i7 kann ALLES ausser Hochdeutsch :D
Na wenn das so ist, probiers mal damit, ungetestet:

Code: Alles auswählen

QuadAddr1 = @Array(Index1, Index2, Index3)
QuadAddr2 = @Array(Index1, Index2, Index3)
!mov rax,[p.v_QuadAddr1]
!mov rdx,[p.v_QuadAddr2]
!mov rax,[rax]
!and rax,[rdx]
!popcnt [p.v_Anzahl],rax
Läuft nur unter x64 und benötigt SSE 4.2.
Ausserdem musst du FASM updaten, von der FASM Seite neuste Version runterladenund im Compilers Ordner von PureBasic fasm.exe ersetzen.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
7x7
Beiträge: 591
Registriert: 14.08.2007 15:41
Computerausstattung: ganz toll
Wohnort: Lelbach

Re: Inline-ASM: Hilfe zu Bit-Count

Beitrag von 7x7 »

Sorry Thorium für die verspätete Rückmeldung. Habe jetzt erst wieder etwas Zeit gefunden.

Habe alles so gemacht wie du geschrieben hast in einer VM, weil ich hier normalerweise unter xp32 arbeite. Es funktioniert nicht. Den POPCNT-Befehl erkennt er nicht.
- alles was ich hier im Forum sage/schreibe ist lediglich meine Meinung und keine Tatsachenbehauptung
- unkommentierter Quellcode = unqualifizierter Müll
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Inline-ASM: Hilfe zu Bit-Count

Beitrag von Thorium »

Ich hatte nen Fehler. Offensichtlich darf bei popcnt der Zieloperand keine Speicherstelle sein.
Hier nun ein funktionstüchtiger Code, funktioniert nun auch unter 32bit, unter 64bit ist er aber erheblich schneller.

Code: Alles auswählen

Procedure Whatever()
  
  Protected QuadAddr1.i
  Protected QuadAddr2.i
  Protected Anzahl.i
  
  Dim ArrayA.q(10, 10, 10)
  
  ArrayA(1, 1, 1) = $FFFFFFFFFFFFFFFF
  ArrayA(2, 2, 2) = $FFFFFFFFFFFFFFFF
  
  QuadAddr1 = @ArrayA(1, 1, 1)
  QuadAddr2 = @ArrayA(2, 2, 2)
  
  CompilerSelect #PB_Compiler_Processor
      
    CompilerCase #PB_Processor_x86
    
      !mov eax,[p.v_QuadAddr1]
      !mov edx,[p.v_QuadAddr2]
      !movq xmm0,[eax]
      !movq xmm1,[edx]
      !pand xmm0,xmm1
      !movd ecx,xmm0
      !popcnt eax,ecx
      !psrlq xmm0,32
      !movd ecx,xmm0
      !popcnt ecx,ecx
      !add eax,ecx
      !mov [p.v_Anzahl],eax
      
    CompilerCase #PB_Processor_x64
      
      !mov rax,[p.v_QuadAddr1]
      !mov rdx,[p.v_QuadAddr2]
      !mov rax,[rax]
      !and rax,[rdx]
      !popcnt rax,rax
      !mov [p.v_Anzahl],rax
      
    CompilerDefault
      
      MessageRequester("", "CPU wird nicht unterstützt")
      
  CompilerEndSelect
  
  MessageRequester("", Str(Anzahl))
  
EndProcedure

Whatever()
Edit: Kleines Code Update, der 32bit Code sollte nun ein wenig schneller sein.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
7x7
Beiträge: 591
Registriert: 14.08.2007 15:41
Computerausstattung: ganz toll
Wohnort: Lelbach

Re: Inline-ASM: Hilfe zu Bit-Count

Beitrag von 7x7 »

Sehr gut! Funktioniert jetzt Prima. Ist auch sehr schnell! :allright:

Wäre schön, wenn es einen eigenen Befehl dafür in PB gäbe. Ich kann mir vorstellen, dass des öfteren mal Bits gezählt werden möchten :)
- alles was ich hier im Forum sage/schreibe ist lediglich meine Meinung und keine Tatsachenbehauptung
- unkommentierter Quellcode = unqualifizierter Müll
Antworten