Logarithmus zur Basis 2

Für allgemeine Fragen zur Programmierung mit PureBasic.
Little John

Beitrag von Little John »

Genau.
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Beitrag von Batze »

Wieso verwendest du zum einen Integer benutzt dann aber doch wieder long in dem asm-teil?

In einer Prozedur krieg ich das ja auch noch hin mit der Variablen, aber dann in einem Makro hab ich keine Ahnung mehr :freak: .
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Little John

Beitrag von Little John »

Ich habe nirgendwo explizit .l verwendet. "value" und "result" nehmen den Default-Typ an. "Procedure.i" kennzeichnet auch den Default-Typ, oder nicht?
Aber egal, wie ich schrieb ist das ganze für PB 4.20, davon gibt's eh keine 64-bit-Version. Also kann man auch "Procedure.l" schreiben.

Wie solch ein ASM-Code für 64 bit aussieht weiß ich nicht.
Ich weiß wer das bestimmt weiß, aber derjenige ist meistens nur im Urlaub fleißig. :mrgreen:

Vor Wurfgeschossen in Deckung gehend, Little John :D
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Little John hat geschrieben:Ich habe nirgendwo explizit .l verwendet. "value" und "result" nehmen den Default-Typ an. "Procedure.i" kennzeichnet auch den Default-Typ, oder nicht?
Aber egal, wie ich schrieb ist das ganze für PB 4.20, davon gibt's eh keine 64-bit-Version. Also kann man auch "Procedure.l" schreiben.

Wie solch ein ASM-Code für 64 bit aussieht weiß ich nicht.
Ich weiß wer das bestimmt weiß, aber derjenige ist meistens nur im Urlaub fleißig. :mrgreen:

Vor Wurfgeschossen in Deckung gehend, Little John :D
So ungefähr müsste es aussehen in 64 bit:

Code: Alles auswählen

   ! mov rax, -1
   ! bsr rax, qword [p.v_value]
   ! mov qword [p.v_result], rax
Aber ich kanns nicht testen, hab kein 64 bit OS und keinen 64 bit Compiler.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Little John

Beitrag von Little John »

Ich ahnte doch, dass es noch einfacher geht:

Code: Alles auswählen

EnableExplicit

Procedure.i BitScanReverse (value)
   ; liefert die Nummer des höchsten gesetzten Bits in 'value'

   ! mov eax, -1
   ! bsr eax, dword [p.v_value]
   ProcedureReturn
EndProcedure

Debug BitScanReverse(8)
Und mit einem Makro geht es z.B. so:

Code: Alles auswählen

EnableExplicit
EnableASM

Define v, res

Macro BitScanRev (value, result)
   ; liefert die Nummer des höchsten gesetzten Bits in 'value'

   v = value
   mov eax, -1
   bsr eax, v
   mov result, eax
EndMacro

BitScanRev(8, res)
Debug res
Ohne "EnableASM" hab ich's mit einem Makro allerdings bis jetzt nicht hinbekommen.

Gruß, Little John
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Du kannst EnableASM an dem Anfang des Macros schreiben, und DisableASM
ans Ende des Macros, so hat es keinen Einfluß auf den Rest des Sources.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Little John

Beitrag von Little John »

ts-soft hat geschrieben:Du kannst EnableASM an dem Anfang des Macros schreiben, und DisableASM
ans Ende des Macros, so hat es keinen Einfluß auf den Rest des Sources.
Gute Idee, danke!

Gruß, Little John
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

So, nun ich doch noch (ohne Wurfgeschosse :mrgreen: !), mir fehlt nur einfach der Sinn der MSB-Ermittlung für diesen Zweck. Also: DarkDragons 64-Bit-Code ist vollkommen richtig und läuft (zur allgemeinen Verwirrung kann man ja anstatt RAX mal z.B. R13 verwenden :mrgreen: ). Wichtig erscheint mir aber im Zusammenhang mit BSR der Hinweis, das in der Literatur (z.B. "Das Assembler-Buch" von T.E. Podschun) BSR falsch beschrieben wird. Demnach wird als Ergebnis Null zurückgeliefert, wenn der 2.Operand Null (also kein Bit gesetzt) ist. Stimmt aber nicht! Das Ergebnis ist für diesen Fall undefiniert, nur das Zero-Flag wird gesetzt. Somit ist Little John´s Code mit Register-Setzen auf -1 durchaus richtig (das Register wird ja durch BSR gesetzt, wenn ...s.o.). Dies müsste aber noch ausgewertet werden. Und wenn ich das schon auswerten muss, kann ich auch vorher den 2.Operanden auf Null testen und dann im Code das Register-Setzen auf -1 einsparen.

Gruß
Helle
Little John

Beitrag von Little John »

Helle hat geschrieben:So, nun ich doch noch (ohne Wurfgeschosse :mrgreen: !)
:D
Helle hat geschrieben:mir fehlt nur einfach der Sinn der MSB-Ermittlung für diesen Zweck.
Das hat sich irgendwie verselbstständigt, nachdem die eigentliche Logarithmus-Frage beantwortet war. :-)
Helle hat geschrieben:kann ich auch vorher den 2.Operanden auf Null testen und dann im Code das Register-Setzen auf -1 einsparen.
Ist das denn besser/schneller? Ich habe tatsächlich genau andersherum gedacht: Wenn ich das Register auf -1 setze, kann ich mir das Auf-Null-Testen sparen.

Gruß, Little John
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Aber dann würde dein Programm mit -1 (alle Bits gesetzt) als Ergebnis weiterrechnen (das Register wird im Null-Fall nicht verändert)! Um eine Überprüfung wird man wohl nicht herumkommen, sonst wird dies eines jener Programme, wo man bei der nachträglichen Fehlersuche das Keyboard auf dem Monitor zerschlägt :mrgreen: .

Gruß
Helle
Antworten