Autor |
Beitrag |
Passi077
      
Beiträge: 125
Win XP
D7 Pers
|
Verfasst: Fr 26.01.07 16:31
Hi,
bin gerade bei meinen ersten Versuchen von Assembler in Delphi (bisher nur auf nem Intel 8051 Assembler programmiert).
Problem1: Ich möchte große Bitzahlen Und-Verknüpfen. Bis 32 Bit mit einem LongWord kein Problem soweit, aber was mache ich, wenn ich größere Zahlen als 32 Bit habe? Des weiteren möchte ich eine logische Rechts-/Linksverschiebung auf diese großen Zahlen anwenden.
Problem2: Wie kann ich denn Arrays in Assembler benutzen?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| function astest(): integer; var Testvar: array [0..1] of longword; asm
MOV Testvar[0], 10011111101b SHR Testvar, 10b MOV EAX, Testvar AND EAX, 1100000001b MOV @Result, EAX
end; |
funktioniert leider nicht ("Operandengröße stimmt nicht überein")
Danke + Grüße
Passi
|
|
OldGrumpy
      
Beiträge: 82
|
Verfasst: Fr 26.01.07 16:57
Am bequemsten ist es, wenn man Zahlen mit mehr als 32 Bit einfach in ausreichend viele 32-Bit-Gruppen aufteilt. Eine Und-Verknüpfung führt man dann halt mit entsprechend vielen Nullbits aufgefüllt für jede Gruppe durch. Bitschiebereien sind auch kein größeres Problem, musst nur halt drauf achten, dass Du immer nur ein Bit auf einmal schiebst und das von einer 32-Bit-Gruppe korrekt zur nächsten weiterleitest. Dafür gibts die Assemblerbefehle RCR und RCL. Ab dem 386er gibts auch elegantere Methoden namens SHLD und SHRD. Ich bin momentan arg erkältet, deswegen spar ich mir mal Beispielcode, Google dürfte da auch einiges liefern 
|
|
Passi077 
      
Beiträge: 125
Win XP
D7 Pers
|
Verfasst: Fr 26.01.07 17:34
Hi,
Danke für die Antwort, somit wäre das Schiebe- und Addierproblem schonmal zumindest teilweise gelöst. Denn ohne die Benutzung von Arrays kann ich damit jetzt immer noch ziemlich wenig anfangen leider
Ich könnte meiner Assembler Funktion natürlich auch einfach die Longword Werte direkt übergeben und die Arrays dann normal in Delphi auslesen. Aber das muss doch auch anders gehen..
|
|
OldGrumpy
      
Beiträge: 82
|
Verfasst: Fr 26.01.07 17:44
Bei welcher Zeile kommt denn die Fehlermeldung? Falls gleich beim ersten MOV, dann ist Delphi vielleicht etwas blond und Du musst wirklich 32 Bit für die Binärzahl benutzen. Es kann natürlich auch sein, dass Delphi diese Adressierungsart (mem, const) nicht kennt, ich kanns so auf Anhieb nicht sagen. Alternativ halt die Adresse des Arrays in ein Register laden und das dann zum Zugriff benutzen.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 28.01.07 19:09
Hi,
Die Nutzung von Arrays in ASM-Sources passiert im Allgemeinen über die Displacements beim Adressieren der Daten.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| type TDWORDArray = array[0..15] of DWORD;
procedure AddArrays(Const InArr1, InArr2: TDWordArray; var OutArr: TDWordArray); asm PUSH EBX MOV EBX, DWORD PTR [ECX] XOR ECX, ECX
PUSHF @@add_loop: POPF MOV ESI, DWORD PTR [EAX+4*ECX] ADC ESI, DWORD PTR [EDX+4*ECX] MOV DWORD PTR [EBX+4*ECX], ESI PUSHF INC ECX CMP ECX, $10 JNZ @@add_loop
POPF POP EBX end; |
Im Normalfall optimiert man das aber noch ein wenig  (Denn mein Prof für Rechnerarchitektur würde mich für den Source prügeln  )
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Allesquarks
      
Beiträge: 510
Win XP Prof
Delphi 7 E
|
Verfasst: Mo 29.01.07 15:02
Eine Implementation mittels des shld/shrd (shift left double precision) Befehls kann man unter meinem Beitrag in open source Projekte>> Bigints große Zahlen ansehen. Die Funktion heißt dort glaube ich (shfl und shfr shiftleft shiftright) die shiften meine Bigints, die sind aber praktisch ein array aus longword.
|
|
Passi077 
      
Beiträge: 125
Win XP
D7 Pers
|
Verfasst: Di 30.01.07 15:55
Hi,
danke für eure Antworten.
Wie ich sehe, schiebt Dein Code allesquarks die Zahlen "von Hand". Ist mir gestern auch gekommen, dass das anders ja gar nicht funktionieren kann. Da nutzt mir auch der Befehl zum Schieben von 2 Registern nix, weil es ja auch vorkommen kann das ich >64Bit Zahlen hab.
Jetzt zweifele ich langsam daran, dass es sich lohnt das Ganze in Assembler zu schreiben. Wenn es fertig ist, soll es eine pixelgenaue Kollisionserkennung mit Hilfe von Alphamasken werden. Jetzt folgendes Beispiel:
2 Objekte, jeweils 50x50 groß.
Die 2 zu kollidierenden Objekte überlappen sich als Rechteck in einem Bereich von 5x30 Pixeln, dieser muss also überprüft werden. Mit Assembler muss ich nun die eine Alpha Maske um die Distanz der Objekte verschieben, in diesem Beispiel also um 45 Bit. Die Gesamtschleife, die es braucht um auf Kollision zu prüfen, läuft nun also 45x30 durch (linienweise überprüft). Dazu kommt noch ein Faktor von x2, da ich die einzelnen Words ja einzeln miteinander Und-Verknüpfen muss. (Hier 2x32Bit)
Programmiere ich das Ganze direkt in Delphi, kann ich einfach mit einem Array arbeiten und nur den zu überprüfenden Bereich Pixel für Pixel überprüfen. Wäre in obigen Beispiel dann nur eine Schleife von 5x30, in der ich dann ganz normal 2 Boolean Werte miteinander verknüpfe.
Lohnt es sich also überhaupt, das in Assembler zu schreiben? Ich weiß ja nicht wie effektiv Delphi compiled und wie viele Zyklen dann jeweils benötigt werden.. und natürlich kann man obiges Beispiel auch umdrehen und dann sieht es eben genau andersrum aus.
Was meint Ihr dazu?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 30.01.07 16:36
Der Compiler von Delphi ist schlichtweg lahmarschig
Aber warum solltest Du den Algorithmus, so wie Du ihn in Delphi schreiben würdest, nicht auch in ASM schreiben können?
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|