Seite 5 von 6

Re: Notation dll Deklaration

Verfasst: 12.11.2009 21:54
von Kaeru Gaman
ermn.. nope.

da musst du irgendwo nen Fehler reingehaun haben.

Code: Alles auswählen

a.b = 1 
a << 7
Debug a

b.b = 1 << 7
Debug b
aber beim rightshift bleibt das höchste Bit erhalten, weil arithmetisch geshiftet wird

Code: Alles auswählen

a.b = 128 
a >> 5
Debug a
Debug Hex( a , #PB_Byte )

Re: Notation dll Deklaration

Verfasst: 13.11.2009 01:29
von mk-soft
Mal ein paar BitShift functions (x86)

Bitshift.pbi

Code: Alles auswählen

;-TOP
; Kommentar     : Bitshift and Rotation
; Author        : mk-soft
; Second Author : 
; Datei         : .pb
; Version       : 1.01
; Erstellt      : 09.06.2007
; Geändert      : 02.01.2009
; 
; Compilermode  :
;
; ***************************************************************************************

; Bitshift left roation
Procedure ROL32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !rol eax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift rotation
Procedure ROR32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !ror eax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left shift
Procedure SHL8(value.b, count.l = 1)

  !xor eax, eax
  !mov al, byte [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shl al, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right shift
Procedure SHR8(value.b, count.l = 1)

  !xor eax, eax
  !mov al, byte [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shr al, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left shift
Procedure SHL16(value.w, count.l = 1)

  !xor eax, eax
  !mov ax, word [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shl ax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right shift
Procedure SHR16(value.w, count.l = 1)

  !xor eax, eax
  !mov ax, word [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shr ax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift left shift
Procedure SHL32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shl eax, cl
  ProcedureReturn
  
EndProcedure

; Bitshift right shift
Procedure SHR32(value.l, count.l = 1)

  !mov eax, dword [p.v_value]  
  !mov ecx, dword [p.v_count]
  !shr eax, cl
  ProcedureReturn
  
EndProcedure

Procedure BSWAP32(value.l)
  !mov eax, dword [p.v_value]
  !bswap eax
  ProcedureReturn
EndProcedure

Procedure.w BSWAP16(value.w)
  !xor eax,eax
  !mov ax, word [p.v_value]
  !rol ax, 8
  ProcedureReturn
EndProcedure


;-Test

x = $80
x = shr8(x,2)
Debug RSet(Bin(x),8,"0")

x = $02
x = shl8(x,2)
Debug RSet(Bin(x),8,"0")

x = $01020304
x = bswap32(x)
Debug RSet(Hex(x),8,"0")

x = $0102
x = bswap16(x)
Debug RSet(Hex(x),8,"0")


x = %1001
x = shl32(x, 4)
Debug Bin(x)

x = %1001
x = shr32(x, 4)
Debug Bin(x)

x = %1001
x = rol32(x, 29)
Debug Bin(x)

x = %1001
x = ror32(x, 5)
Debug Bin(x)

FF :wink:

Re: Notation dll Deklaration

Verfasst: 13.11.2009 09:25
von six1
der entscheidende Test ist:

b.b = 1 << 7
Debug RSet(Bin(b),8,"0")

Die Ausgabe lautet: %11111111

während der inline Debuger einfach -128 zeigt!

Das muss man schon wissen :D

Wenn ich also eine Variable Byte nehme, ein Bit über Schiebeoperatoren setze und das msb gesetzt wird, werden ALLE Bits gesetzt.
Ich denke nicht, dass ich einen Fehler im Programmm hatte, außer dem, dass ich aus unwissenheit über das signed Flag einen Typ Byte genommen habe. Ich habe den Typ durch.c ersetzt... eigentlich auch nicht ganz fein :D

Re: Notation dll Deklaration

Verfasst: 13.11.2009 10:24
von ts-soft
six1 hat geschrieben:Ich habe den Typ durch.c ersetzt... eigentlich auch nicht ganz fein :D
Solange Du Dein Programm nicht mit Unicode Flag kompilierst kein Problem aber nach ein paar
Monaten, wenn man sein Programm überarbeitet, hat man sowas evtl. vergessen und wundert
sich über die Fehler.
Falls Du PB 4.40 verwendest, solltest Du besser den Typ .a benutzen! Da klappts auch mit dem
Unicode-Nachbarn :mrgreen:

Gruß
Thomas

Re: Notation dll Deklaration

Verfasst: 13.11.2009 10:30
von helpy
six1 hat geschrieben:der entscheidende Test ist:

b.b = 1 << 7
Debug RSet(Bin(b),8,"0")

Die Ausgabe lautet: %11111111

während der inline Debuger einfach -128 zeigt!
Da liegt der Haken woanders!
Der folgende Code:

Code: Alles auswählen

a.b = 1
a << 7
Debug a
Debug Bin(a)
Debug RSet(Bin(a),8,"0")
Debug Bin(a & $FF)

b.b = 1 << 7
Debug b
Debug Bin(b)
Debug RSet(Bin(b),8,"0")
Debug Bin(b & $FF)
liefert als Ergebnis:

Code: Alles auswählen

-128
1111111111111111111111111111111111111111111111111111111110000000
11111111
10000000
-128
1111111111111111111111111111111111111111111111111111111110000000
11111111
10000000
D.h. Bin() erwartet einen QUAD-Wert und wandelt a bzw. b in einen QUAD-Wert um !!!
RSet nimmt nun einfach die ersten 8 Bits und zeigt diese an, weil der String Bin() zu lang ist!
==> Das kannst Du nur umgehen, indem Du mit "& $FF" arbeitest, wie oben im Beispiel.

cu, helpy

Re: Notation dll Deklaration

Verfasst: 13.11.2009 10:37
von six1
RSet nimmt nun einfach die ersten 8 Bits und zeigt diese an
:allright: eben wird es klarer! Das sind die 8 höchstwertigen Bits des quad!
Also lag der Fehler in meinem Programm lediglich in der Anzeige der Werte und nicht an der tatsächlichen Ausgabe...
Hier muss ich gestehen, habe ich die Portpins auch nicht jedes Mal geprüft :|

gut, dass wir drüber gesprochen haben :lol:

Re: Notation dll Deklaration

Verfasst: 13.11.2009 13:47
von Kaeru Gaman
noch eine Lösung: benutze das Typeflag für Bin().
das ist neu, steht nur in der Kontexthilfe in der Statusbar, nicht im Kapitel in der Help.

Code: Alles auswählen

b.b = 1 << 7
Debug Bin( b, #PB_Byte )

Re: Notation dll Deklaration

Verfasst: 13.11.2009 13:58
von six1
was ich aber noch nicht verstehe ist, warum belegt "bin()" bei der Wandlung alles mit "1" vor?

Muss das so?

Re: Notation dll Deklaration

Verfasst: 13.11.2009 14:30
von Kaeru Gaman
ich habe keine Ahnung, warum das so ist. bei Hex() ohne Typeflag tritt das gleiche auf.
das liegt wahrscheinlich einfach an der Routine selber, also wie Fred das implementiert hat damit es schnell und knackig ist.
man muss halt dran denken, das Typeflag zu verwenden, dann ist alles Wölkchen.

Re: Notation dll Deklaration

Verfasst: 13.11.2009 14:43
von helpy
six1 hat geschrieben:was ich aber noch nicht verstehe ist, warum belegt "bin()" bei der Wandlung alles mit "1" vor?

Muss das so?
Weil beide Zahlen dem Wert -128 entsprechen:

Code: Alles auswählen

b.b = %10000000
q.q = %1111111111111111111111111111111111111111111111111111111110000000
Debug b
Debug q
Debug-Ausgabe:

Code: Alles auswählen

-128
-128