Seite 2 von 6

Verfasst: 14.08.2008 16:48
von ZeHa
Kaeru Gaman hat geschrieben:PS:
> sind die Vergleichsoperatoren <= und >= langsamer als < und > ?
ich würde mal raten, dass das garnicht feststeht, sondern von beiden zu verarbeitenden werten abhängt....
Den CMP-Befehl gibt es ebenfalls in mehreren Ausführungen, je nachdem ob z.B. zwei Bytes verglichen werden, oder zwei Words, oder zwei DWords, oder ein Byte mit einem DWord, oder ein DWord mit einem Pointer auf ein DWord usw. usf., aber es spielt keine Rolle dabei, ob er < oder <= vergleicht, weil das wie gesagt erst beim Sprung entschieden wird und nicht beim Vergleich.

Verfasst: 14.08.2008 16:50
von Kaeru Gaman
aye, ok... thnx

Verfasst: 14.08.2008 17:07
von Helle
Ab Pentium benötigen alle bedingten Sprünge (also ausser JMP) die selbe Taktzeit. Ausnahme: JCXZ/JECXZ (wertet das (E)CX-Register aus).
Vergleiche (CMP) können nur mit identischen Register/Variablen-Grössen durchgeführt werden. Ausnahme: Der zweite Operand ist eine Konstante (Zahlenwert).
Das Beispiel mit Sign funktioniert mit PB, weil für Rechts-Shift SAR verwendet wird; kann bei anderen Sprachen fehlschlagen (signed-unsigned). Wer SAR für Divisionen durch 2-Potenzen einsetzt, muss bei negativen Werten aufpassen, weil SAR anders rundet (in Richtung minus unendlich). Kleines Beispiel:

Code: Alles auswählen

Debug -101 / 4     ;-25 wie erwartet
Debug -101 >> 2    ;-26 !
Gruss
Helle

Verfasst: 14.08.2008 17:11
von ZeHa
Helle hat geschrieben:Vergleiche (CMP) können nur mit identischen Register/Variablen-Grössen durchgeführt werden. Ausnahme: Der zweite Operand ist eine Konstante (Zahlenwert).
Naja die Zahl der Ausnahmen ist schon recht groß.
Laut Intel-Beschreibung gibt's für CMP insgesamt 14 verschiedene Opcodes, je nachdem wie groß die Werte sind (8, 16 oder 32 Bit) und ob sie als Konstante, als Referenz oder als Register angegeben wurden.

EDIT: Und zwar nicht nur für den zweiten Wert, sondern auch für den ersten


(Zumindest laut diesem Dokument: click, Seite 116)

Verfasst: 14.08.2008 17:22
von AND51
Helle hat geschrieben:Wer SAR für Divisionen durch 2-Potenzen einsetzt, muss bei negativen Werten aufpassen, weil SAR anders rundet (in Richtung minus unendlich). Kleines Beispiel:

Code: Alles auswählen

Debug -101 / 4     ;-25 wie erwartet
Debug -101 >> 2    ;-26 !
Um Stringoperationen unicodefähig zu machen, muss man die Anzahl Characters ja in Bytes umrechnen. D. h. 5 Zeichen sind entweder 5 oder 10 Bytes.

Vorher habe ich immer

Code: Alles auswählen

x*SizeOf(Characters)       ; Ergibt 1 (ASCII) oder 2 (Unicode)
verwendet; mittlerweile nehme ich aber immer

Code: Alles auswählen

x<<#PB_Compiler_Unicode         ; Konstante ist immer 0 oder 1
Kann man doch gefahrlos tun, oder?

Und dies ist genau ein Beispiel was ich mit meiner Aussage "Bit schneller als Multplikation". Stimmt das so?

Verfasst: 14.08.2008 17:32
von Helle
@ZeHa: Ist ein Handbuch für den PentiumII, aktuell ist Dokument 253666.
Ändert aber nichts: Du willst z.B. Byte mit DWord vergleichen, und das geht nicht. Darum geht´s.

Gruß
Helle

Verfasst: 14.08.2008 17:38
von AND51
Kaeru Gaman hat geschrieben:
(sizeof(int) * CHAR_BIT - 1)
bekommt man 0 für positiv und 1 für negativ.
wenn man 1 und -1 haben will, muss man noch 1-2*sign rechnen.
Ooooder man rechnet

Code: Alles auswählen

sign = 1|v>>31
:)

Verfasst: 14.08.2008 17:48
von Kaeru Gaman
AND51 hat geschrieben:Ooooder man rechnet

Code: Alles auswählen

sign = 1|v>>31
:)
kann ich nicht nachvollziehen....?
klappt zwar, aber rechne das mal bitte vor, ich steig nicht durch...

Verfasst: 14.08.2008 18:15
von AND51
Komisch, jetzt wo du fragst und ich länger drüber nachdenke: Ich weiß es auch nicht (wirklich)... :freak:

Ich versuchs trotzdem, denn so habe ich es mir zumindest gedacht:

Durch das >>31 bleibt nur das Vorzeichen-Bit (jenes ganz links) übrig, welches für eine positive oder null (0) oder negative (1) Zahl steht. Dieses Bit wird an erster Stelle geholt und dann wird |1 angewendet;
so gesehen (und das verstehe ich nicht) dürfte das Ergebnis doch immer 1 sein?!

Der 31er-Rechtsschift ergibt jedoch nicht 1, sondern 1<<32-1 :o
Hilfe, ich komme auch durcheinander...

Bis auf das ganz linke Bit müss(t)en doch alle anderen verloren gehen, oder?


// Edit:
Hilfe, was ist hier los?

Code: Alles auswählen

one=1
Debug Bin(one<<31>>31)
Hier müsste doch 1 das Ergebnis sein?

Verfasst: 14.08.2008 18:55
von Danilo
AND51 hat geschrieben:// Edit:
Hilfe, was ist hier los?

Code: Alles auswählen

one=1
Debug Bin(one<<31>>31)
Hier müsste doch 1 das Ergebnis sein?
PB macht signed Shifts, und da wird beim Rechtsverschieben um 31
das Vorzeichen aufgefüllt.
Was Du machen möchtest ist bestimmt (a>>31)&1.

Code: Alles auswählen

Macro SignL(a)
  ((a>>31)&1)
EndMacro

a.l = -1
Debug SignL(a)
a + 1
Debug SignL(a)