Inline Assembler und die Register

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
FosJonas
Beiträge: 121
Registriert: 12.11.2008 19:31

Inline Assembler und die Register

Beitrag von FosJonas »

Guten tag,

Da ich mich zurzeit mit Assembler in kombination mit Purebasic beschäftige habe ich jetzt auch schon eine frage bezüglich der Register:

Laut der Hilfe kann man ja nur die Register eax, edx und ecx benutzen (ist das bei 64 bit eigentlich auch so? Da hat man ja viel mehr Register als bei 32bit)
Da dass natürlich einschränkt habe ich mir gedacht ich speicher einfach vor dem Assembler code alle Register im Hauptspeicher , und setze sie danach wieder, was ja eigentlich dazu führt das durch den Assemblercode keine veränderung im Register auftritt:

Hier mal der Code:

Code: Alles auswählen

Macro StartASM()
  
  !mov rdx,[v_ASM]
  !mov [rdx],r8
  !mov [rdx+8],r9
  !mov [rdx+16],r10
  !mov [rdx+24],r11
  !mov [rdx+32],r12
  !mov [rdx+40],r13
  !mov [rdx+48],rax
  !mov [rdx+56],ecx
  
EndMacro

Macro StopASM()
  
  !mov rdx,[v_ASM]
  !mov r8,[rdx]
  !mov r9,[rdx+8]
  !mov r10,[rdx+16]
  !mov r11,[rdx+24]
  !mov r12,[rdx+32]
  !mov r13,[rdx+40]
  !mov rax,[rdx+48]
  !mov ecx,[rdx+56]
  
EndMacro
Die Variable ASM ist in diesem fall einfach ein Speicherbereich in dem das ganze gespeichert wird.
Das Problem: es treten immer noch "Ungültige Speicherzugriffe" bei Purebasic befehlen auf.
Aber warum ist das so? Kann man mit den Registern noch mehr machen als nur Werte zu speichern?

Bzw. ich habe jetzt hier im Forum auch Assembler code gesehen der mehr als die 3 Register nutzt, gibt es da vielleicht irgendeinen Trick, bzw. etwas was ich beachten muss damit es eben nicht zu den "Ungültigen Speicherzugriffen" kommt?

Wäre dankbar für eure Hilfe.
Purebasic 5.10 | Kubuntu 12.04 (64 bit) | Opera 12.01 | Nvidia GT 9800
Xubuntu 12.04 (64 bit) | Intel HD Graphis (Onboard)
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Inline Assembler und die Register

Beitrag von Danilo »

FosJonas hat geschrieben:Die Variable ASM ist in diesem fall einfach ein Speicherbereich in dem das ganze gespeichert wird.
Ist dieser Speicherbereich auch groß genug?

Code: Alles auswählen

Global ASM.i

Macro StartASM()
  
  !mov rdx,[v_ASM]
  !mov [rdx],r8
  !mov [rdx+8],r9
  !mov [rdx+16],r10
  !mov [rdx+24],r11
  !mov [rdx+32],r12
  !mov [rdx+40],r13
  !mov [rdx+48],rax
  !mov [rdx+56],ecx
  
EndMacro

Macro StopASM()
  
  !mov rdx,[v_ASM]
  !mov r8,[rdx]
  !mov r9,[rdx+8]
  !mov r10,[rdx+16]
  !mov r11,[rdx+24]
  !mov r12,[rdx+32]
  !mov r13,[rdx+40]
  !mov rax,[rdx+48]
  !mov ecx,[rdx+56]
  
EndMacro


Procedure writeLn(A$)
    StartASM()
        PrintN(A$)
    StopASM()
EndProcedure


ASM = AllocateMemory(60)

If OpenConsole()
    For i = 0 To 255
        writeLn(Chr(i))
    Next i
    Input()
EndIf


FreeMemory(ASM)
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
FosJonas
Beiträge: 121
Registriert: 12.11.2008 19:31

Re: Inline Assembler und die Register

Beitrag von FosJonas »

Erstmal danke für deine Antwort.

Genug Speicher habe ich auf jedenfall, habe zur Sicherheit einfach mal 600 byte angefordert was ja locker reichen sollte.

Was du allerdings mit deinem Code aussagen willst ist mir nicht so ganz klar.
Purebasic 5.10 | Kubuntu 12.04 (64 bit) | Opera 12.01 | Nvidia GT 9800
Xubuntu 12.04 (64 bit) | Intel HD Graphis (Onboard)
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Inline Assembler und die Register

Beitrag von Danilo »

FosJonas hat geschrieben:Was du allerdings mit deinem Code aussagen willst ist mir nicht so ganz klar.
Damit will ich aussagen, daß das hier ohne Probleme läuft.

Die Methode finde ich zwar komisch, aber ich sehe keine Probleme und
es läuft in der Praxis. RDX wird so nicht gesichert, das fällt mir dazu noch ein.

Wenn Du also genau mit dieser Methode Probleme hast und es so verwenden
möchtest, wäre es gut mal einen Code zu sehen wo es damit Probleme gibt.
Der gezeigt Code läuft ja mit dieser Methode richtig.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
FosJonas
Beiträge: 121
Registriert: 12.11.2008 19:31

Re: Inline Assembler und die Register

Beitrag von FosJonas »

Ja der Code funktioniert da ja kein Assembler Code darin vorkommt.

Als Beispiel mal diesen Code:

Code: Alles auswählen

Global ASM.i = AllocateMemory(600)
Global rsp.i

Macro StartASM()
  
  !mov rdx,[v_ASM]
  !mov [rdx],r8
  !mov [rdx+8],r9
  !mov [rdx+16],r10
  !mov [rdx+24],r11
  !mov [rdx+32],r12
  !mov [rdx+40],r13
  !mov [rdx+48],rax
  !mov [rdx+56],ecx
  
EndMacro

Macro StopASM()
  
  !mov rdx,[v_ASM]
  !mov r8,[rdx]
  !mov r9,[rdx+8]
  !mov r10,[rdx+16]
  !mov r11,[rdx+24]
  !mov r12,[rdx+32]
  !mov r13,[rdx+40]
  !mov rax,[rdx+48]
  !mov ecx,[rdx+56]
  
EndMacro

Procedure Test()
  
  !mov [v_rsp],rsp
  Debug rsp
  StartASM()
  !mov rsp,3
  StopASM()
  !mov [v_rsp],rsp
  Debug rsp
  
EndProcedure

Test()
Eigentlich müsste ja das 1. und 2. debuggen den gleichen Wert ausgeben , ohne das !mov rsp,3 tut es das auch.
Wen ich allerdings diesen Teil wie oben einfüge, dann hängt es das Programm an dieser stelle (!mov rsp,3) auf und der Debugger meldet:
"Das mit dem Debugger ausgeführte executable wurde unerwartet beendet"

Das liegt wahrscheinlich daran das ich was wichtiges übersehen bzw. falsch verstanden habe, aber ich weiß einfach nicht was.

Edit: :oops: Hier ist mir jetzt ein Fehler unterlaufen der mir erst im nachehinein aufgefallen ist, da ich hierfür einen anderen Code verwende (da der alte zu lang wäre) habe ich ausversehen ein anderes Register genutzt, ich werde das gleich mal überprüfen ob es nur daran lag.
Purebasic 5.10 | Kubuntu 12.04 (64 bit) | Opera 12.01 | Nvidia GT 9800
Xubuntu 12.04 (64 bit) | Intel HD Graphis (Onboard)
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Inline Assembler und die Register

Beitrag von Danilo »

FosJonas hat geschrieben:Eigentlich müsste ja das 1. und 2. debuggen den gleichen Wert ausgeben , ohne das !mov rsp,3 tut es das auch.
Wen ich allerdings diesen Teil wie oben einfüge, dann hängt es das Programm an dieser stelle (!mov rsp,3) auf und der Debugger meldet:
"Das mit dem Debugger ausgeführte executable wurde unerwartet beendet"
- RSP wird in StartASM/StopASM nicht gesichert/wiederhergestellt.
- den Stackpointer so zu benutzen ist keine gute Idee
- Debug sollte man bei ASM-Zeugs auch meiden, da es versteckte, komische Dinge tut.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
FosJonas
Beiträge: 121
Registriert: 12.11.2008 19:31

Re: Inline Assembler und die Register

Beitrag von FosJonas »

Habe leider erst jetzt Zeit zum Antworten gefunden.

So nach zahlreichen Tests und durch die Hilfe von Danilo (vielen Dank an dich) habe ich das Problem nun gelöst, habe tatsächlich ein Register übersehen und dieses nicht gesichert, und der Code selber hatte einen Ungültigen Speicherzugriff (wobei ich dachte das dieser vom Assembler und nicht von PB mit verweis auf die Procedure gemeldet wird).

Zum Debug, meinst du damit nur den Befehl Debug, oder den Debugger ansich? Das wäre nämlich ziermlich blöd.
Purebasic 5.10 | Kubuntu 12.04 (64 bit) | Opera 12.01 | Nvidia GT 9800
Xubuntu 12.04 (64 bit) | Intel HD Graphis (Onboard)
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Inline Assembler und die Register

Beitrag von Thorium »

Zum sichern von registern nutzt man eigentlich die push instruktion, welche den registerinhalt auf den stack legt und später stellt man die register mit pop wieder her.
Dabei muss beachtet werden das sich lokale variablen auch auf dem tack befinden und sih deren index dementsprechend verschiebt.

Ich halte es immer so das ich asm code und pb code strikt trenne. Dann gibts keine probleme. Das heisst ich schreibe proeduren komplett in asm und hau keien pb befehle dazwischen. Register sichern ist natürlich trotzdem pflicht.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
FosJonas
Beiträge: 121
Registriert: 12.11.2008 19:31

Re: Inline Assembler und die Register

Beitrag von FosJonas »

Ja das man Assembler und PB code trennen sollte habe ich auch schon festgestellt, die Push und Pop Befehle habe ich allerdings total vergessen, das dürfte das sichern und wiederherstellen ja extrem beschleunigen.

Mein Problem wäre damit ja sehr gut gelöst, danke an alle.
Purebasic 5.10 | Kubuntu 12.04 (64 bit) | Opera 12.01 | Nvidia GT 9800
Xubuntu 12.04 (64 bit) | Intel HD Graphis (Onboard)
Antworten