fastcall mit ml
-
MASM unterstützt ja angeblich kein fastcall.
Da hab ich ein wenig überlegt und mir folgendes Zusammengebastelt:
.686 .model flat, stdcall fcalltest equ @fcalltest@8 .code fcalltest PROC SYSCALL mov eax, edx add eax, ecx ret fcalltest endp end
Und das ganze dann so in C++ verwenden:
#include <iostream> using namespace std; extern "C" { int __fastcall fcalltest(int, int); } int main() { int a= 4, b=5; cout << a << " + " << b << " = " << fcalltest(a,b) << endl; cin.clear(); cin.ignore(cin.rdbuf()->in_avail()); cin.get(); return 0; }
Das ganze scheint zu funktionieren. Meine Fragen: Ist das "richtiger" Code? kann das schief laufen?
-
Ich sehe da erst mal kein Problem. Wenn MASM mit seinen Macros kein fastcall unterstuetzt, dann benutze diese Macros eben einfach nicht.
-
und was hat das mit macros zu tun?
-
Auch die Art wie MASM seine komplizierteren Strukturierungen wie zB. Prozeduren mit Parameterlisten und festgelegter Aufrufkonvention umsetzt, aehnelt der Verwendung von komplexen vorgegebenen Macros. Dh. praktisch steckt dahinter eine 1:1-Ersetzung mit nach einfachen Regeln ausgewaehlten Codes oder Symbolen.
Dh., dass du ohne Probleme Codes schreiben kannst, ohne MASMs Annehmlichkeiten wie Prozedurdefinitionen mit nach Aufrufkonventionen geregelten Parameterlisten mit netten Variablennamen und auf magische Weise angelegte Stack Frames zu benutzen, indem du die entsprechenden Befehle (als Mnemonics) und Adressen fuer Parameterzugriffe der Aufrufkonvention entsprechend selbst ausschreibst, statt MASMs gezauberte Macro-Symbole zu benutzen.
Damit bist du natuerlich auch nicht mehr deren Beschraenkungen wie nicht unterstuetzten Aufrufkonventionen unterlegen.
-
Nobuo T,
ich versteh nicht was an PROC, INVOKE… komplizier sein soll - diese Anweisungen ersparen einem Zeit und machen den Code besser lesbar. In den meisten Fällen gibt es keinen nennenswerten Mehrwert den stackframe selber anzulegen oder die Parameter von Hand zu puschen.Und mit Zauberei hat das nichts zu tun! Programmieren mit Assembler setzt auch eine bisschen Hintergrundwissen voraus - wenn man das nicht hat, dann erscheint einem natürlich so Manches an MASM wie Zauberei. (soll keine Unterstellung sein
)
grüße, masm
-
Sorry, hatte den Benutzernamen nicht gelesen und dachte zuerst, du waerst der OP.
Wie auch immer, ich habe nicht vor, hier eine Diskussion ueber die Vorzuege vs. Probleme von MASM mit dir zu fuehren (es sei denn der OP aendert das Topic). Wenn du das unbedingt diskutieren willst, mach dazu bitte einen neuen Thread auf.Deshalb nur so viel:
"komplex" war vergleichend zu normalen anderen Macros gemeint. Damit war keine weitere Wertung beabsichtigt, auch nicht in Bezug auf die praktische Anwendung.
-
OP meldet sich jetzt mal :P.
Meine Sorge war eher, ob ich mit dem Code relativ sicher sein kann, dass er so auf anderen Rechnern (oder späteren Versionen von MASM) kompiliert/ausgeführt wird. Für mich sieht sowas nämlich aus, als wäre es ein "hack" und damit etwas, was nicht im Sinne von "natürlicher" MASM-Programmierung ist. Daher dann ohne "Recht" auf Gültigkeit.
-
Solange du keine Parameter bei PROC angibst (und benutz) ist es so ok.
Nur noch mal als Anmerkung:
M$ fastcall (x86-32):
- die ersten zwei Parameter, die kleiner gleich 4 Byte sind werden durch ecx und edx übergeben: z.B. byte, word, dword, Zeiger. Ausnahme: float's werde aber über den stack übergeben.
- alle anderen (größeren) Datentypen werden auf dem stack abgelegtBsp: __fastcall fnc(__int64,int,float,long); hier wäre dann ecx = int edx = long [esp+4] = __int64 [esp+4+8] = float
(hoffe das es stimmt
)
Im Übrigen ist es in masm möglich diese Problem zu lösen: Prolog und Epilog Marcos definieren - währe aber wohl kaum in deinem sinn dich damit zu erschlagen, da man ohne hin etwas Tricksen müsste.