Assember, welche Register pushen?

Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

sinjin

Betreff: Assember, welche Register pushen?

BeitragSo, Apr 12, 2015 5:18
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

Xeres

Moderator

BeitragSo, Apr 12, 2015 11:42
Antworten mit Zitat
Benutzer-Profile anzeigen
~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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Silver_Knee

BeitragSo, Apr 12, 2015 15:01
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Apr 12, 2015 16:50
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Apr 12, 2015 19:04
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Apr 12, 2015 19:57
Antworten mit Zitat
Benutzer-Profile anzeigen
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)

Xeres

Moderator

BeitragSo, Apr 12, 2015 20:25
Antworten mit Zitat
Benutzer-Profile anzeigen
~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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Silver_Knee

BeitragSo, Apr 12, 2015 22:56
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink
 

sinjin

BeitragSo, Apr 12, 2015 23:35
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

BladeRunner

Moderator

BeitragMo, Apr 13, 2015 17:19
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Apr 13, 2015 18:31
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink

Was willst du mit ES anfangen? Das ist ein Segmentregister (alle: CS, DS, ES, FS, GS, SS). Du programmierst nicht für DOS Razz
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

BeitragMo, Apr 13, 2015 19:03
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Apr 13, 2015 19:10
Antworten mit Zitat
Benutzer-Profile anzeigen
P.S. Leider ist c2=c0/c1, c1=c0 mod c1 immer noch schneller als meine Routine Very Happy Ich habe mir das halt so gedacht, das man nur ein IDIV verwendet, leider scheint ein CALL etwas langsamer zu sein.

Thunder

BeitragMo, Apr 13, 2015 19:20
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Razz
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 Wink

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 Razz
 

sinjin

BeitragMo, Apr 13, 2015 22:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Lieber Thunder, wenn du mein Beispiel nimmst und NICHT EBP pushst(es bleibt ein selten dämliches Wort Smile, läuft das Programm nicht mehr. Ich weiss das die CPU einen internen Cache hat, früher waren das mal 32 oder 64 Byte, aus der Zeit komme ich halt(20 Jahre?), und jetzt will ich wieder mit Asm anfangen, zumindest um einige Prozesse zu beschleunigen. Ich mag zwar Hochsprachen, aber wenn ich mir einige .release-Dateien anschaue..omg, dass die Compiler immer noch nicht besser geworden sind....naja, z.B. wird bei jeder Funktion EAX auf Null gesetzt obwohl gar kein Rückgabewert erwartet wird, das andere fällt mir grade nicht ein, aber sich so einen Fauxpas als Compiler zu leisten....naja, hauptsache es läuft. Und ja, ich will ein paar CPU-Takte sparen, besonders wenn die in einem Loop stattfinden, z.B. um Pixelberechnungen durchzuführen. Bilder sind nicht unbedingt klein Very Happy Früher wollte ich mal nen Compiler schreiben, der direkt mit der EXE arbeitet, ein Compiler der direkt Assembliert und deassembliert....Aber ich fand es super schwer schon alleine den Source zu parsen und ich habe hohen Respekt davor.
 

sinjin

BeitragMo, Apr 13, 2015 22:46
Antworten mit Zitat
Benutzer-Profile anzeigen
@Thunder Nicht falsch verstehen, ich bin froh, das du so eine Bereicherung des Forums bist!

Thunder

BeitragMo, Apr 13, 2015 23:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich lass mich nicht aus der Ruhe bringen Smile

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 Very Happy Und ich beantworte auch gern Fragen in dem Zusammenhang, soweit ich eben was dazu weiß. Oft ist es trotzdem so, dass der GNU C/C++ Compiler einen effizienteren Assemblercode raushaut, als die meisten Programmierer schreiben könnten - wenn es sich nicht um Asm-Profis handelt.

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

BeitragDi, Apr 14, 2015 0:15
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Very Happy Trotzdem finde ich allgemein besser Wissenschaft frei zu teilen, als damit Geld zu verdienen und alles für sich zu behalten(also das Wissen).
 

sinjin

BeitragDi, Apr 14, 2015 0:19
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Apr 14, 2015 2:03
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group