Assember, welche Register pushen?
Übersicht

sinjinBetreff: Assember, welche Register pushen? |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wenn ich eine Funktion in Assembler schreibe, welche Register/Segmente (EBX,EDI,ES,FS..) müssen auf den Stack gelegt werden? Ist es z.B. sicher ES zu verwenden ohne das Register zu pushen? Eine Liste wäre toll. | ||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
~VERSCHOBEN~ Dieser Thread passte nicht in das Forum, in dem er ursprünglich gepostet wurde. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Silver_Knee |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich kenn mich jetzt nicht so arg mit Assembler aus, aber ich glaube, da das eine der Grundfunktionalitäten ist, wirst du z.B. hier fündig. | ||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Sry, aber wenn ich so suche hat das nichts mehr mit BlitzMax zu tun, ich will ja gerade wissen, welche Register nicht verändert werden dürfen damit mein in BlitzMax geschriebenes Programm weiter läuft. | ||
![]() |
Silver_Knee |
![]() Antworten mit Zitat ![]() |
---|---|---|
BlitzMax nutzt Standard Aufrufe. Das steht zumindest bei "Interfacing with C". Du musst dir den Aufruf halt raus suchen. Kannst ja auch ne Funktion aufrufen und das Programm disassembliern. | ||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Code: [AUSKLAPPEN] 'test.bmx
import "test.s" extern function divmod(nr%,dv% var,md% var)="sjdivmod" endextern repeat local ms%=millisecs() local cc% repeat local c0%=101,c1%=21,c2% divmod c0,c1,c2 ' c2=c0/c1 ' c1=c0 mod c1 cc:+1 until (millisecs()-ms>1000) print cc forever Code: [AUSKLAPPEN] ;test.s
format MS COFF public _sjdivmod section "code" code ;in pushd - nr ;in out pushd - adr div ;out pushd - adr mod _sjdivmod: push ebp mov ebp,esp xor edx,edx mov edi,[ss:ebp+12] cmp dword [ds:edi],edx jz sjdivmod_out mov eax,[ss:ebp+8] idiv dword [ds:edi] mov [ds:edi],eax sjdivmod_out: mov edi,[ss:ebp+16] mov [ds:edi],edx pop ebp ret So, muss ich EDI pushen, oder EDX? Erst hatte ich EBX anstatt EDI, aber ohne EBX zu sichern, stürzt das Programm ab. Welche Register muss man sichern? Ich hoffe so ists verständlich (dabei sagen mir Leute ich solle ein Buch schreiben, lol) |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
~VERSCHOBEN~ Ich habe nichts von BlitzMax in der Fragestellung erkannt... |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Silver_Knee |
![]() Antworten mit Zitat ![]() |
---|---|---|
Okay, ich hab in der BMAX-Hilfe nix mehr zu stdcall gefunden. Das war wohl noch B3D-Wissen, dass ich da vermischt habe...
Also: http://en.wikibooks.org/wiki/B...ing_with_C Die BlitzMax-Hilfe sagt dass Funktionen in C++ mit extern "C" eingeleitet werden müssen. http://en.wikibooks.org/wiki/X...rn_.22C.22 Hier steht, dass das "typically CDECL" ist. http://en.wikibooks.org/wiki/X...ions#CDECL Darüber findest du Beispiel-Code für CDECL. Wie gesagt, ich kann kein Assembler, aber der Code unterscheidet sich bei den Befehlen eben gerade bei den von dir angesprochenen Registern. Alles mit Google geschafft ![]() |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das hilft mir leider alles nicht weiter bzw. weiss ich schon. Es steht zwar nichts darüber da, was ich eigentlich wissen will und ich bin mir sicher in C(++) reicht es das EPB-Register zu sichern, das scheint bei BlitzMax nicht zu reichen, da das Programm nicht läuft wenn ich EBX verändere. | ||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ist jetzt brute force, aber sicher einfach alles und lass nach und nach Register aus der Sicherung weg. Wenn es nicht mehr läuft (im Zusammenspiel mit einem nicht-Trivialen Programm, bei dem der Aufruf des Assemblercodes unter verschiedenen Bedingungen geschieht) dann weisst Du was benötigt wird. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Der Caller muss sich selbst um EAX, ECX und EDX kümmern. Die aufgerufene Funktion (Callee) kümmert sich um EBX, ESI und EDI.
Quelle: http://www.cs.virginia.edu/~ev...s/x86.html Das sind Konventionen, du findest eventuell Assembly-Codestücke, die sich nicht daran halten. Gängige C/C++-Compiler berücksichtigen das. Ich denke auch der BlitzMax-Compiler. Kleines Zuckerl: EBP musst du nicht sichern, es wird aus Bequemlichkeit gemacht, da du dann in EBP den wert von ESP beim Eintritt in die Funktion speicherst und mit fixen Offsets auf die Parameter ([ebp+8], [ebp+12], ... für 4 byte datentypen) und auf die lokalen Variablen ([ebp-4], [ebp-8], ... dito) zugreifen kannst ![]() Was willst du mit ES anfangen? Das ist ein Segmentregister (alle: CS, DS, ES, FS, GS, SS). Du programmierst nicht für DOS ![]() Ich kann's dir nicht mit Sicherheit sagen, aber ich denke, wenn du ES mal von Hand selber neu lädst oder spätestens wenn du damit auf irgendwas zugreifst, segfaultet dein Programm. |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
EBP(ESI) muss man sehr wohl sichern, sonst geht es nicht. Klar kann ich statt EBP auch EDI,ESI oder EBX nehmen. Ferner weiss ich, das ES keine direkte Speicherstelle im Protectedmode darstellt. Allerdings meine ich mal gelesen zu haben, das bei jedem Festplattenzugriff kurz in den Real Mode gewechselt wird...
So wie ich das jetzt verstanden habe, (und je nachdem welche Register meine Funktion verwendet), müssen folgende Register gesichert werden: EBX, EDI, und ESI. |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
P.S. Leider ist c2=c0/c1, c1=c0 mod c1 immer noch schneller als meine Routine ![]() |
||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
sinjin hat Folgendes geschrieben: EBP(ESI) muss man sehr wohl sichern, sonst geht es nicht.
Nein. ESI schon, EBP nicht. Wenn du das nochmal behauptest, schmeiss ich dir ein Gegenbeispiel vor die Augen ![]() Wenn du einen C-Code mit -O3 kompilierst, macht es nicht Mal der C-Compiler. sinjin hat Folgendes geschrieben: Ferner weiss ich, das ES keine direkte Speicherstelle im Protectedmode darstellt.
Habe nicht behauptet, dass du das nicht weißt. sinjin hat Folgendes geschrieben: Allerdings meine ich mal gelesen zu haben, das bei jedem Festplattenzugriff kurz in den Real Mode gewechselt wird...
Also wenn du mit Windows >= XP oder einem Windows der NT-Reihe arbeitest oder irgendeinem halbwegs modernen großen Betriebssystem kannst du das vergessen. Die haben alle ihre Protected Mode Treiber für Festplatten. sinjin hat Folgendes geschrieben: So wie ich das jetzt verstanden habe, (und je nachdem welche Register meine Funktion verwendet), müssen folgende Register gesichert werden:
EBX, EDI, und ESI. Genau ![]() Zu deinem Beispiel: Selbst wenn das nicht optimiert wird (bei den großen C++-Compilern könnte ich mir vorstellen, dass die das können), hast du einen entscheidenden vorteil bei c2=c0/c1; c1=c0 mod c1: Du änderst nicht die Reihenfolge der Ausführung -> d.h. der Prozessor hat die Befehle schon geladen, bevor sie ausgeführt werden (http://de.wikipedia.org/wiki/Pipeline_(Prozessor)). Und c1, c0 und c2 sind spätestens nach dem ersten Befehl im Cache, also kostet die zweite Rechnung kaum noch Zeit. Was sinnvoll wäre, ist eben eine inline-Optimierung, ich weiß aber nicht, ob du dir daran die Zähne ausbeißen willst, um ein paar Prozessortakte zu sparen ![]() |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Lieber Thunder, wenn du mein Beispiel nimmst und NICHT EBP pushst(es bleibt ein selten dämliches Wort ![]() ![]() |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@Thunder Nicht falsch verstehen, ich bin froh, das du so eine Bereicherung des Forums bist! | ||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich lass mich nicht aus der Ruhe bringen ![]() Ne schau, ich hab halt schon bissi was gemacht mit Assembler und auch in Zusammenhang mit BlitzMax. Deswegen mische ich mich gerne ein, wenn es darum geht Wenn du einfach ebp nicht pusht, funktioniert es natürlich nicht mehr. Ich zeig dir trotzdem mal ein kleines bsp: Code: [AUSKLAPPEN] ; So sieht das eben normalerweise aus
; Dies ist eine Funktion die 42 zurückgibt funktion1: push ebp mov ebp, esp mov eax, 42 leave ret ; Dies ist auch eine Funktion, die 42 zurückgibt funktion2: mov eax, 42 ret So meinte ich das. Und wenn du irgendwo relative Adressen in Bezug zu ebp hast, müsstest du die umschreiben (ist nicht immer leicht, aber möglich - besonders für Compiler). Es ist immer toll, Leute auf zu treffen, die Assembler lernen wollen - für mich zumindest ![]() Habe mal eine Metaball-Demo zuerst in BlitzMax und dann in BlitzMax + C (wobei die Hauptschleife und gesamte Programmlogik in C war und nur das Zeichnen in BMax) geschrieben und ausprobiert, wobei letzteres viel schneller war. Einfach nur, um zu schauen, wie der Unterschied ist. Wenn du deine Pixelberechnungen machst, versuch mal den Loop als ganzes in C zu schreiben. Einzelne Teile im Loop zu ändern hätte nur sinn, wenn du inline assembly zur verfügung hättest. Es stimmt dass der BlitzMax-Compiler seine Macken hat. Gerade bei Float-Operationen - was mir mal auffiel: Für das Berechnen der wurzel aus einem float wird eine Funktion aufgerufen die (wenn ich mich richtig erinnere) original einen befehl ausführt (fsqrt). Ich habe mal einen Postprozessor für die Assemblerdateien vom BlitzMax-Compiler geschrieben, der alles nochmal durchgegangen ist und ersetzungen durchgeführt hat. Aber große Erfolge gab es kaum, oft waren die "Optimierungen" auch langsamer, sodass ich sie wieder wegnahm. Was wirklich extrem boostet sind MMX und SSE. Wenn du diese CPU-Erweiterungen nutzt hast du (Spitze) +1000% Geschwindigkeit bei einzelnen Codepassagen. Übrigens: Bin auch schon mehrmals kläglich an Compilerbau gescheitert. PS: CPU-Caches sind mittlerweile verdammt groß. L1-Cache zwischen 16 und 64 KB (Quelle: http://www.elektronik-kompendi...309291.htm) So, nach diesem langen Post haben wir alle einen Keks verdient. |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Stimmt, damals hat mich auch teilweise gewundert, das Pascal schneller war als mein Code. Ich finde es auch immer wieder gut Leute zu treffen die den "alten Scheiss" nicht aufgegeben haben, denn daher kommt das schliesslich alles. Ich habe iwo schon mal meine ganzen Libs hochgeladen, vllt hast du das schon, aber hier nochmal alles was ich in ASM gemacht habe: http://www.file-upload.net/dow...s.zip.html
Tja, beim Wurzelziehen bin ich zu dem Ergebnis gekommen (zumindest bin ich selber drauf gekommen, weil ich erst seit 4 Jahren Inet habe)....1+3+5+7=16 (genau 4 Mal), also alle ungeraden Zahlen haben was damit zu tun, ich habe mich damit nicht weiter beschäftigt, aber ich schliesse nicht aus, das es eine super-duper-Methode gibt um die Prims zu berechnen (als alle Menschen vor uns), es hat bisher nur keiner "entdeckt"/erfunden. Wie der Erfinder von Melodyne Peter Neubäcker, der fragt sich auch warum es keiner vor ihm entdeckt hat....Aber das driftet jetzt zu sehr ins philosophische als iwie nützlich zu sein ![]() |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jep, und im Grunde ist die ganze Mathematik nur Philosophie, Mathe hat sich nur durchgesetzt weil niemand anderes daher kam, und was besseres/anderes vorgeschlagen hat. Das heisst nicht, dass es nicht was besseres als Mathe gibt, die Möglichkeit schliesst sich nur aus den Gedanken der Menschen aus, WEIL Mathe funktioniert. | ||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich empfinde Mathe iwie wie Musik, es muss alles stimmig sein, ich habe vor nem Jahr ein Song gemacht, es kommen einfach alle Töne der Tonleiter vor, und es klappt! Auf der anderen Seite kann ich es nicht wirklich beschreiben bzw sagen was genau in meinem Hirn passiert, egal was man macht, stellt es euch graphisch vor(egal welches Koordinatensystem). Dadurch lösen WIR ALLE einige Probleme bzw verstehen mehr Dinge als reine Philosophie. | ||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group