Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 04, 2025 18:57

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Jan 23, 2003 16:17 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
tach,

ich hab hier ne Berechnung um von MOD music
dateien die Position zu bekommen.

Die berechnung stimmt, die MASM Code von der berechnung sieht so aus:

Code:
  1.  
  2.  
  3.     .elseif uMsg == WM_TIMER
  4.  
  5.         invoke BASS_ChannelGetPosition, ModHandle
  6.  
  7.         mov edx, eax
  8.  
  9.         and eax, 0000000011111111b                      
  10.  
  11.         sar edx, 16
  12.  
  13.         invoke wsprintf, ADDR buffer1, ADDR szFormatString, eax, edx, ModName
  14.  
  15.         invoke SendMessage, hStatus, SB_SETTEXT, 0, ADDR buffer1    
  16.  
  17.  


und mein delphi code so:

Code:
  1.  
  2.  
  3.   type
  4.  
  5.     TByte2Array = array [0..1] of Byte;
  6.  
  7.  
  8.  
  9.     function GetMusicPos(Pos: Int64): TByte2Array;
  10.  
  11.     asm
  12.  
  13.         MOV EDX, EAX
  14.  
  15.         AND EAX, 0000000011111111b
  16.  
  17.         SAR EDX, 16
  18.  
  19.     end;
  20.  
  21.  


wie bekomm ich nun EDX in Result[0] und EAX in Result[1] ???
Peil asm so gut wie gar nicht...
Wenn mir jemand mal die zeilen erklären könnte wärs cool.

SAR EDX, 16 ist doch das gleiche wie

Code:
  1.  
  2.  
  3.   Result[0] := Pos SHR 16;
  4.  
  5.  


oda irr ich mich ???


danke schonmal für antworten.

matane,
Finalspace


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jan 23, 2003 17:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Zitat:
Code:
  1.  
  2.  
  3.   type
  4.  
  5.     TByte2Array = array [0..1] of Byte;
  6.  
  7.  
  8.  
  9.     function GetMusicPos(Pos: Int64): TByte2Array;
  10.  
  11.     asm
  12.  
  13.         MOV EDX, EAX
  14.  
  15.         AND EAX, 0000000011111111b
  16.  
  17.         SAR EDX, 16
  18.  
  19.     end;
  20.  
  21.  

wie bekomm ich nun EDX in Result[0] und EAX in Result[1] ???
Peil asm so gut wie gar nicht...
Wenn mir jemand mal die zeilen erklären könnte wärs cool.

Ich sag wieder das, was ich oft sagen muss : ein Blick in die Delphi-Hilfe genügt, denn dort steht drin, das Assemblerfunktionen 8-bit Werte im AL-Register als Ergebnis zurückgeben, 16-Bit Werte im AX-Register und (das was du brauchst) 32 Bit-Werte im EAX-Array.
So solltest du also einen gültigen Rückgabewert erhalten :
Code:
  1.  
  2.  
  3.   type
  4.  
  5.     TByte2Array = array [0..1] of Byte;
  6.  
  7.  
  8.  
  9.     function GetMusicPos(Pos: Int64): TByte2Array;
  10.  
  11.     asm
  12.  
  13.         MOV EDX, EAX
  14.  
  15.         AND EAX, 0000000011111111b
  16.  
  17.         SAR EDX, 16
  18.  
  19.         MOV EAX, EDX
  20.  
  21.     end;
  22.  
  23.  


Zitat:
SAR EDX, 16 ist doch das gleiche wie
Code:
  1.  
  2.  
  3.   Result[0] := Pos SHR 16;
  4.  
  5.  

oda irr ich mich ???

Ja.Du irrst, SAR steht für Shift Arithmetic Right, während SHR für ein logisches Verschieben nach Rechts steht.In der Praxis müsste oben genanntes aber trotzdem funktionieren (kenne leider nur den ASM-Befehlssatz des 8085 gut, beim 8086 sind meine Kentnisse nicht ganz so gut, deshalb ist die Angabe ohne Gewähr)

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 23, 2003 20:26 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Mai 06, 2002 10:50
Beiträge: 42
Wohnort: [Auch diese Steine können Sie klauen...]
Um die Ausführungen von SOS ein wenig zu vertiefen:

SHR schiebt alle Bits um ein Bit nach rechts, während das niederwertigste Bit ins Carryflag wandert und das höchstwertigste mit 0 aufgefüllt wird.

SAR schiebt ebenfalls alle Bits um ein Bit nach rechts. Dabei wird das niederwertigste Bit in das Carryflag geschoben, während das höchstwertigste Bit seinen Wert beibehält. „SARst“ du also einen ursprünglich negativen Wert (höchstwertiges Bit#32 = 1), dann behält er – im Gegensatz zu SHR – seinen negativen Wert bei. Deshalb auch Shift Arithmetical Right.

Bei deinem Rückgabewert sehe ich ein paar Stolperfallen. Erstens denke ich nicht, dass der Wert einfach so im EAX-Register zurückgegeben wird. Du musst bedenken, dass du einen selbst definierten Typ zurückgibst, der ja eigentlich nur 16Bit breit ist. Ich weiß, jetzt kommt der Einwand, dass es ja ein Array ist, Arrays sind aber unter Pascal lediglich Zeiger. Ich glaube also eher, dass hier im EAX ein Zeiger auf eine Stelle im Speicher übergeben wird, der dann auf deinen gewünschten Wert zeigt. Genau sagen kann ich dir das aber im Moment auch nicht, aber das beste Mittel, das auszuprobieren, ist: CPU-Fenster im Debugger aufmachen, ein bisschen try&error-Coding, und einfach mal schauen, was passiert.

Dann übergibst du einen Int64 an die Funktion. Bedenke, dass EAX nur 32Bit breit ist, wo bleiben also die restlichen 32Bit? Oder sind die irrelevant? Dann würde ich besser nur einen Integer/Cardinal übergeben, Int64 hat so seine ganz speziellen Rechenregeln (z.B. müssen 32Bit-Werte vorher gecastet werden, bevor du ein richtiges Ergebnis bekommst, sonst erfolgt keine richtige Berechnung – mehr dazu in der Delphi-Hilfe) und ist auch sonst kein – wie soll ich sagen – „konformer“ Datentyp.

Gruß


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 23, 2003 21:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Mai 06, 2002 10:50
Beiträge: 42
Wohnort: [Auch diese Steine können Sie klauen...]
Habe mir gerade den Code noch mal angesehen.

Wenn ich das richtig verstanden habe, dann passiert in der ASM-Routine folgendes:
[LIST]Die Funktion BASS_ChannelGetPosition wird aufgerufen. Diese liefert einen 32Bit-Wert zurück.
[*] Die nächste Funktion wsprintf erwartet ein paar Parameter, darunter auch eax und edx, die anscheinend den zuvor zurückgegeben „aufgedröselten“ eax erwarten, weil die Funktion das so will.[LIST]
Bleibt also nur noch die Frage: Wie implementiere ich das in Delphi?
Wie wäre es denn mit folgendem Code?
Code:
  1. Procedure myProc;
  2.  
  3. var
  4.  
  5.   BassResult     : integer;
  6.  
  7.   BassResultHigh : integer;
  8.  
  9.   BassResultLow  : integer;
  10.  
  11. begin
  12.  
  13.   BassResult := BASS_ChannelGetPostion(ModHandle);
  14.  
  15.   
  16.  
  17.   BassResultHigh := BassResult and $FF00;
  18.  
  19.   BassResultLow  := BassResult and $00FF;
  20.  
  21.   
  22.  
  23.   Wsprintf(@buffer1, PChar(szFormatString), BassResultLow, BassResultHigh, PChar(ModName);
  24.  
  25. end;


Natürlich weiß ich jetzt nicht genau, wie die anderen Parameter alle definiert sind, aber ein bisschen was muss ich ja noch dir überlassen… ;)

Gruß


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jan 24, 2003 08:45 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Also ich muss immer wieder staunen, wieviel wissn delphi mitglieder gegenüber mir haben, obwohl ich soviele jahre schon programmiere weiss ich nicht annähernd was andere wissn.
Ich hab grossen respekt vor euch, das solltet ihr wissn.

Danke mal für die viele antworten ;)

Ich versteh so gut wie gar nix von ASM, hab die Hilfe mir angeschaut, konnte aber nicht viel mit anfangen.

ich weiss ja nicht einmal wofür die ganzen befehle sind... warum hat SOS am ende der ASM routine MOV EAX, EDX geschrieben ???

eigentlich versteh ich nicht eine zeile ASM code :(
ist echt traurig, aber naja... ich werd mich anstrengen und es lernen.

Ich glaube das hat so keinen sinn, kennt hier einer nen Wirklich gutes Deutsches Tutorial über Assembler z.b Inline Delphi Assembler ??


matane,
Finalspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jan 24, 2003 08:58 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Mai 06, 2002 10:50
Beiträge: 42
Wohnort: [Auch diese Steine können Sie klauen...]
Sorry, vergiss meinen Code oben, der ist nämlich absoluter Schwachsinn...da sind eine Reihe von Denkfehlern drin. Das kommt halt davon, wenn man den Code nicht testet...

Ich versuche über die Mittagspause eine berichtigte Version zu erstellen.

Wenn du ein gutes Assember-Tut suchst, dann schau mal beim <a href='http://www.programmierer-board.de' target='_blank'>Programmiererboard</a> vorbei. Dort gibt es eine Koryphäe namens Marilin oder so ähnlich in der Assembler-Ecke, der hat ein Tut ins Deutsche übersetzt, das ich sehr gut fand. Außerdem müsste der eigentlich ein Buch veröffentlicht haben...

Gruß
Armin


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Läuft
BeitragVerfasst: Fr Jan 24, 2003 09:09 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Alles klar funzt:

Code:
  1.  
  2.  
  3. type
  4.  
  5.  &nbsp;TByte2Array = array [0..1] of Byte;
  6.  
  7.  
  8.  
  9.  &nbsp;function GetMusicPos(Pos: Int64): TByte2Array;
  10.  
  11.  &nbsp;asm
  12.  
  13.  &nbsp; &nbsp; MOV EDX, EAX
  14.  
  15.  &nbsp; &nbsp; AND EAX, 0000000011111111b
  16.  
  17.  &nbsp; &nbsp; SAR EDX, 16
  18.  
  19.  &nbsp; &nbsp; MOV EAX, EDX
  20.  
  21.  &nbsp;end;
  22.  
  23.  
  24.  
  25. var
  26.  
  27.  &nbsp;BA : TByte2Array;
  28.  
  29.  &nbsp;Basspos_High,
  30.  
  31.  &nbsp;Basspos_Low : Byte;
  32.  
  33. begin
  34.  
  35.  &nbsp;pos := BASS_ChannelGetPosition(mods[listbox1.itemindex]);
  36.  
  37.  &nbsp;BA := GetMusicPos(pos);
  38.  
  39.  &nbsp;Basspos_Low := pos mod 16;
  40.  
  41.  &nbsp;Basspos_High := BA[0];
  42.  
  43.  &nbsp;label7.Caption := Format(szFormatString, [Basspos_High, Basspos_Low]);
  44.  
  45. end;
  46.  
  47.  


aber irgendwie vergisst die ASM funktion den TByte2Array[1] wert, der wird einfach auf 0 gesetzt. :( wäre cool wenn das mal einer vervollständigen könnte.

Thx,
Finalspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jan 24, 2003 10:30 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Mai 06, 2002 10:50
Beiträge: 42
Wohnort: [Auch diese Steine können Sie klauen...]
Okay, ich versuchs nochmal, gestern war ja nun absolut nicht mein Tag...:(

Die nachgebildete Funktion könnte z.B. so aussehen:
Code:
  1. function GetMusicPos(pos : integer) : TInteger2Array;
  2.  
  3.  &nbsp;//-----------------
  4.  
  5.  &nbsp;function SAR_16(Op : integer) : integer; assembler;
  6.  
  7.  &nbsp;asm
  8.  
  9.  &nbsp; &nbsp;MOV EAX, Op &nbsp;
  10.  
  11.  &nbsp; &nbsp;SAR EAX, 16
  12.  
  13.  &nbsp;end;
  14.  
  15.  &nbsp;//-----------------
  16.  
  17.  
  18.  
  19. begin
  20.  
  21.  &nbsp;Result[0] := pos and $00FF;
  22.  
  23.  &nbsp;Result[1] := SAR_16(pos);
  24.  
  25. end;


Der Befehl MOV EAX, Op ist zwar nicht unbedingt nötig, da der übergebene Parameter sowieso in EAX steht, allerdings kannst du jetzt sicher sein, dass der richtige Wert in EAX steht! Ich weiß nicht genau, wie Delphi die Parameterübergabe handelt, aber das scheint von Fall zu Fall verschieden zu sein. Manchmal stehen die Parameter in ECX und EDX, manchmal auch in EAX. Ich denke mal, das ist von Anzahl und Typ der Parameter abhängig.

Ich habe den Int64 durch einen Integer ersetzt, weil dir die oberen 32Bit des Int64 sowieso flöten gehen. Ich gehe mal davon aus, dass du wie ich auf einem 32Bit-Betriebssystem arbeitest. Willst du unbedingt mit 64Bit arbeiten, dann musst du die ganze Sache ganz anders aufziehen.

Den TByte2Array habe ich auf TInteger2Array erweitert, weil dir sonst vielleicht wichtige Informationen verloren gehen. Wie ich in der MASM-Proc gesehen habe, wird dort ja auch mit Integern respektive Cardinals gearbeitet.

Sodele, hoffe gehilft zu haben.

Gruß


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jan 27, 2003 10:38 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jul 12, 2002 07:15
Beiträge: 916
Wohnort: Dietzhölztal / Hessen
Programmiersprache: C/C++, Obj-C
@Finalspace: der Befehl MOV EAX, EDX bedeuted: Kopiere den Inhalt von Register EDX nach EAX. Da die Funktion von Delphi als Rückgabe den Wert in EAX erwartet, er aber in EDX liegt, muss er eben von EDX nach EAX kopiert werden. Wichtig ist dabei übrigens, dass man beachtet, welche Register unverändert wieder die Funktion verlassen müssen. Die müsste man dann eben vorher mit PUSH & POP sichern bzw. wiederherstellen. Wer mit InLine oder anderen Assembler-Funktionen arbeiten will, sollte sich vorher GUT UND INTENSIV die Hilfe zu dem Thema in Delphi anschauen, um unnötigen Ärger zu ersparen!

_________________
Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: Majestic-12 [Bot] und 6 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 16 Queries | GZIP : On ]