Autor Beitrag
Allesquarks
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Do 24.11.05 18:11 
Wie kann ich bei call bestimmen, in welche von mehreren überladenen Funktionen ich springen möchte? Oder geht das nicht und ich muss sie umbenennen.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 24.11.05 18:39 
Du meinst, in folgender Situation:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Procedure A(A: Integer); overload;
begin
    DoSomething;
end;

Procedure A(A: String); overload;
begin
    DoSomething;
end;

procedure B; assembler;
asm
    CALL    A //Aber welche nun ;-)
end;


Leider ist mir für diese Situation keine Lösung bekannt, da man nicht einmal Funktionsaliase (per Konstanten) definieren kann (IMHO).

Sowas geht AFAIR nicht (bin mir aber nicht sicher):

ausblenden Delphi-Quelltext
1:
2:
3:
Const
    A1 = Procedure (A: Integer) = A;
    A2 = Procedure (A: String) = A;


Ist bisher ungetestet ... Falls es funktioniert, wäre eine Rückmeldung wünschenswert...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Allesquarks Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Do 24.11.05 18:57 
Hab das mal ausprobiert. Hat leider nicht geklappt. Immerhin kann man es offenbar insoweit steuern, dass er immer die im Quelltext zuerst erscheinende Funktion aufruft. Trotzdem Dankeschön werde es dann anders lösen.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Do 24.11.05 21:49 
Die IMHO eleganteste Möglichkeit für derartiges ist, bei überladenen Funktionen generell ein Name Mangling ähnlich des C++-Manglings einzuführen und anschließend über überladene Funktionen ein "Demangling" (es ist kein echtes (da nicht automagisch), aber der Effekt ist ein ähnlicher) durchzuführen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure A_i(A: Integer); // mangled
begin
    DoSomething;
end;

procedure A_s(A: String); // mangled
begin
    DoSomething;
end;

procedure A(A: Integer); overload;
begin
  A_i();
end;

procedure A(A: String); overload;
begin
  A_s();
end;



procedure B;
begin
  A(SomeString); // String-Variante
asm
    CALL    A_i // Integer-Variante
end;
end;


Vergrößert zwar den Code etwas, aber da der Compiler sowas nicht von alleine macht, muss man halt selbst Hand anlegen.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
I.MacLeod
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 109



BeitragVerfasst: Sa 26.11.05 19:38 
Bens (ich darf dich doch so nennen? ^^) Vorschlag war prinzipiell richtig, nur die Syntax hat nicht gestimmt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
procedure foobar(s: string); overload;
begin
  showmessage(s);
end;

procedure foobar(i: integer); overload;
begin
  foobar(inttostr(i));
end;

const
  foobar_s: procedure(s: string) = foobar;
  foobar_i: procedure(i: integer) = foobar;

...

  asm
    mov  eax, 42
    call foobar_i
  end;
  foobar(42);
  foobar('foo');
  foobar_i(42);
  foobar_s('foo');


Wenn mans so macht wie tommie-lie und der Compiler es unterstützt, würde ich function A(...) evtl noch inlinen.

_________________
{$APPTYPE CONSOLE}uses SysUtils;const a='{$APPTYPE CONSOLE}uses SysUtils;const a=%s;begin write(Format(a,[#39+a+#39]))end.';begin write(Format(a,[#39+a+#39]))end.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 26.11.05 20:04 
user profile iconI.MacLeod hat folgendes geschrieben:
Wenn mans so macht wie tommie-lie und der Compiler es unterstützt, würde ich function A(...) evtl noch inlinen.
Richtig, aber inline ist nach wie vor nur ein Hint. Bei einem derartigen Einzeiler *sollte* der Compiler selbstständig erkennen, daß er das Ding inlinen kann.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 27.11.05 18:56 
@I.MacLeod: Genial, dass ich richtig geraten hab ;-) Werd's gleich nutzen ;-)
Darfst mich aber auch BenBE nennen ;-)

@Syntaxfehler: War Flüchtigkeit stell ich grad fest :P = statt :

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Allesquarks Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Fr 08.09.06 15:02 
Ich grabe das hier nochmal aus: Gleiches Problem nur dass ich gerade versuche das auf Methoden zu erweitern. Die Delphihilfe ist bei Methodenzeigern ja mal recht deutlich. Nur leider kriege ich das nicht zum laufen. Auch nicht in der von denen dargestellten minimal Beispiel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type pmymethod : procedure (zahl1:integer):integer of object;

var myvar:pmymethod;

implementation

procedure Class1.test1(zahl1:integer):integer;
begin

end;

...

myvar:=class1.test1; //quittiert delphi mit incompatible types pmymethod und procedure grrr wo doch test1 klar ne ///////Methode ist


Wenn ich das anders mache mymethod als functionenzeiger, dann insistiert er auf einmal, dass ja class1.test1 doch schließlich eine Methode sei und nicht einer procedur zugewiesen werden kann.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 09.09.06 13:33 
user profile iconAllesquarks hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
procedure Class1.test1(zahl1:integer):integer;
//...
myvar:=class1.test1; //quittiert delphi mit incompatible types pmymethod und procedure grrr wo doch test1 klar ne ///////Methode ist
Wenn Delphi nicht plötzlich case-sensitive geworden ist, ist das keine Methode, weil "Class1" kein Objekt bezeichnet. Erzeuge ein Objekt von Class1, dann sollte die Zuweisung myvar := obj.test1; gehen.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Allesquarks Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Sa 09.09.06 18:54 
In der Hilfe steht sogar dass man damit Methoden von Instanzen!!! zuweist, alllerdings widerspricht dann deren eigenes Beispiel dem. Zusätzlich habe ich auch noch die Schwierigkeit, dass ich ausgerechnet den/einen Konstruktor aufrufen möchte, ich also noch gar keine Instanz habe. Falls das partout nicht klappen sollte bzw. unmöglich ist, könnte man ja stattdessen versuchen die entsprechenden Funktionen des Konstructors classcreate etc. manuell aufzurufen Tipps bezüglich dessen würde ich ebenfalls zu schätzen wissen.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 09.09.06 19:06 
user profile iconAllesquarks hat folgendes geschrieben:
[...] Tipps bezüglich dessen würde ich ebenfalls zu schätzen wissen.
Wenn du einen Pointer auf einen Konstruktor benötigst, lässt sich eventuell dein Design ändern. Wie sieht selbiges denn aus, was sind die Anforderungen? Eventuell kommst du mit meta-classes (type TBlubb = class of TSomeClass) weiter.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Allesquarks Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: So 10.09.06 18:47 
Ich glaube nicht dass mir klassenreferenzen da helfen, die benutz ich aber an anderer Stelle schon exzessiv.

Mein Design:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
type TBigint = class(TZahl)

...

constructor create(vorzeichen:boolean;zahl:int64);overload;//streng genommen ist dass hier ein zweckentfremdeter int64 da ordinaltyp
constructor create(vorzeichen:boolean;zahl array [0..2of dword);overload;
constructor create(vorzeichen:boolean;zahl:array [0..3of dword);overload;

end;

implementation


in einer anderen Unit nun in etwa Code ist stellvertretend:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function mul(zahl1,zahl2:int64):TZahl;
asm
 
...

@@create3dwordbigint:

//hier wird der zweite Constructor aufgerufen

@@create4dwordbigint:

//hier wird der dritte Constructor aufgerufen

end;


wobei wir auch schon bei einer Lösung wären: Einfach nur die Klasse createn und dann in assembler initialisieren, denn nur das ist ja der Grund für den ganzen Aufriss hier, aber gerade das wollte ich ja umschiffen. Zumal ich das nicht verstehe:
DelhiCompiler werden doch nicht für jedes Objekt einzelne Codesegmente anlegen, sondern vielmehr hat eine Funktion oder MEthode einen festen Platz im Segment, der sinnvollerweise sich wahrscheinlich auch nicht ändert. Warum kann es nicht einfach einen Befehl geben, der mir diese Addresse gibt. Wahrscheinlich würde es sogar funktionieren wenn ich im disassembler einfach den hex wert copiere. Das ist mir dann aber doch zu unelegant.
Also wirkt jetzt vielleicht penetrant aber ich will das entweder mit den Methodenzeigern machen oder ich muss dann wohl oper übel die Instanz in assembler initialisieren.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: So 10.09.06 19:20 
user profile iconAllesquarks hat folgendes geschrieben:
in einer anderen Unit nun in etwa Code ist stellvertretend:
Den blick ich so nicht ;-)
Sieht doch eigentlich so aus, als wüsstest du in deinem Code, welche Klasse und wlechen Konstruktor du haben möchtest, warum rufst du den nicht einfach auf? Andererseits weiß ich nicht mehr genau, wie die eigentliche Initialisierung des Objektes abläuft, es könnte sein, daß ein "CALL TSomeClass.Create" nicht das tun wird, was du dir versprichst, schon allein weil in Delphi das Erzeugen von Objekten Compiler Magic ist, und die umgehst du mit Assembler.

Allesquarks hat folgendes geschrieben:
wobei wir auch schon bei einer Lösung wären: Einfach nur die Klasse createn und dann in assembler initialisieren, denn nur das ist ja der Grund für den ganzen Aufriss hier, aber gerade das wollte ich ja umschiffen.
Assembler-Block verlassen und anschließend wieder einsteigen? Geht zumindest beim G++ und GCC, sollte theoretisch auch beim DCC gehen, wenn der Compiler dem Programmierer nicht mehr Knüppel zwischen die Beine wirft, als er unbedingt muss.

Allesquarks hat folgendes geschrieben:
DelhiCompiler werden doch nicht für jedes Objekt einzelne Codesegmente anlegen, sondern vielmehr hat eine Funktion oder MEthode einen festen Platz im Segment, der sinnvollerweise sich wahrscheinlich auch nicht ändert.
Richtig. Deswegen der Hidden Parameter "self". Wäre es andersrum, würde "self" nicht über einen Parameter implementiert werden müssen.

Allesquarks hat folgendes geschrieben:
Warum kann es nicht einfach einen Befehl geben, der mir diese Addresse gibt.
Syntaktisch wäre das "@TSomeClass.SomeMethod", aber ich weiß nicht, was das für ein Datentyp ist. In C++ ist es ein Zeiger auf einen Functor relativ zum Objekt. Also das, was implementationsabhängig die VMT ist.

Allesquarks hat folgendes geschrieben:
Wahrscheinlich würde es sogar funktionieren wenn ich im disassembler einfach den hex wert copiere. Das ist mir dann aber doch zu unelegant.
Und gefährlich, sobald sich die Basisadresse des Images ändert, beispielsweise weil der PE-Loader Binaries jetzt woanders hinlädt oder das Image, das du kompilierst, als Bibliothek in einen anderen Prozess geladen wird. Für sowas brauchst du schon Unterstützung vom Linker.

Ich sehe das Problem darin, daß Konstruktoren und Destruktoren weder gewöhnliche Methoden noch gewöhnliche Funktionen sind. Ich fürchte, du musst tatsächlich das Objekt in Assembler assemblieren, wenn du nicht Assembler und Hochsprache mischen kannst und/oder willst. Ansonsten würde ich bei der Multiplikation das Ergebnis erstmal in einen Buffer schreiben und anschließend in einem Pascal-Einzeiler das Objekt mit diesem Buffer erzeugen. Wie Borland den Int64 intern layoutet weiß ich nicht, aber möglicherweise wäre es dafür nötig, deine Klasse so zu ändern, daß es das ABI von Int64 weiterspinnt (Big oder Little Endian?). Hat also ebenfalls seine Schattenseiten.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Allesquarks Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Mo 11.09.06 08:41 
user profile icontommie-lie hat folgendes geschrieben:

Sieht doch eigentlich so aus, als wüsstest du in deinem Code, welche Klasse und wlechen Konstruktor du haben möchtest, warum rufst du den nicht einfach auf? Andererseits weiß ich nicht mehr genau, wie die eigentliche Initialisierung des Objektes abläuft, es könnte sein, daß ein "CALL TSomeClass.Create" nicht das tun wird, was du dir versprichst, schon allein weil in Delphi das Erzeugen von Objekten Compiler Magic ist, und die umgehst du mit Assembler.

Richtig ich weiß ja auch welchen ich aufrufen möchte bei call TBigintzahl.create nimmt er nur immer den ersten in der Liste. Compilermagic ich hoffe nicht denn ich ruf an sehr vielen stellen über dl,$01; und eax Klassenreferenz den Constructor auf funktioniert bisher auch einwandfrei.

user profile icontommie-lie hat folgendes geschrieben:
Allesquarks hat folgendes geschrieben:
wobei wir auch schon bei einer Lösung wären: Einfach nur die Klasse createn und dann in assembler initialisieren, denn nur das ist ja der Grund für den ganzen Aufriss hier, aber gerade das wollte ich ja umschiffen.
Assembler-Block verlassen und anschließend wieder einsteigen? Geht zumindest beim G++ und GCC, sollte theoretisch auch beim DCC gehen, wenn der Compiler dem Programmierer nicht mehr Knüppel zwischen die Beine wirft, als er unbedingt muss.

Ich meinte eigentlich nicht den assemblerblock verlassen, wobei ich das in der Funktion auch ungern tue, sondern über call TObject.create die Klasse als Rohform erhalten und dann im assembler zu initialisieren, wobei meine Frage ja eigentlich dzu dient das nicht zu tun aber es scheint sich jetzt so abzuzeichnen.

user profile icontommie-lie hat folgendes geschrieben:
Allesquarks hat folgendes geschrieben:
Warum kann es nicht einfach einen Befehl geben, der mir diese Addresse gibt.
Syntaktisch wäre das "@TSomeClass.SomeMethod", aber ich weiß nicht, was das für ein Datentyp ist. In C++ ist es ein Zeiger auf einen Functor relativ zum Objekt. Also das, was implementationsabhängig die VMT ist.

Stehen denn auch die nicht virtuallen Methoden in der VMT. Nun ja eigentlich logisch, da die Klassen ja darüber identifieziert werden.

Nun ja vielleicht endet es ja auch damit dass ich die Konstruktoren nicht überlade sondern einfach anders benenne. Aber das ist so unelegant.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 11.09.06 18:48 
Versuche einmal den Ansatz, den ich oben für normale Prozeduren vorgeschlagen hab ...

ausblenden Delphi-Quelltext
1:
var Create1 : Procedure (vorzeichen:boolean;zahl:int64) of object = TBignumint.Create;					

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Allesquarks Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Mo 11.09.06 21:05 
Bin gerade auf Turbo Delphi umgestiegen. Auch da funktioniert es nicht. Im Gegenteil jetzt sagt er inkompatible typen integer und boolean. Nun ja ich wars jetzt Leid und da ich nicht groß rummurksen wollte, sind das jetzt einfach alles Funktionen mit unterschiedlichen Namen und damit auch aus inline asm aufrufbar. Desweiteren sind es jetzt auch keine Konstruktoren mehr, denn beim Aufruf produzierten die Exceptions (gut ebx und co waren noch nicht wieder auf den alten Werten aber der constructor mit Namen create läuft einwandtfrei).

Vielen Dank nochmal auch dass einem hier versucht wird zu helfen, wenn man es auch selber lösen kann.

Hier im Übrigen einmal der Verursacher:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
type TBigintzahl = class(TZahl)
   zahl:array of longword;

...

end;

type TInt64zahl = class(TZahl)
zahl:int64;

...

end;


constructor TBigintzahl.create(laenge:integer=0);
begin
   setlength(zahl,laenge);
   vorzeichen:=false;
end;

{
 --------   --------           --------   --------
 |   1  |   |   2  |     *     |   3  |   |   4  |
 --------   --------           --------   --------

------------------------------------------------------------

 --------   --------
 |13 hi |   |13 low|
 --------   --------

            --------   --------
            |23 hi |   |23 low|
            --------   --------

            --------   --------
            |14 hi |   |14 low|
            --------   --------

                       --------   --------
                       |24 hi |   |24 low|
                       --------   --------
}

function mul(zahl1:TInt64zahl;zahl2: TInt64zahl): TConstant;
asm
      push ebx;
      push esi;
      push edi;
      push ebp;
      //register freigemacht

      mov ecx, dword ptr [eax].TInt64zahl.zahl+$04;//1
      mov ebx, dword ptr [eax].TInt64zahl.zahl;   //2

      xor eax,eax;
      test ecx,$80000000;//ob es vorzeichen hat
      jz @@weiter1;
      inc eax;
      not ebx;  //Vorzeichen ändern von Zahl 1
      not ecx;
      add ebx,$01;
      adc ecx,$00;
    @@weiter1:

      mov edi, dword ptr [edx].TInt64zahl.zahl+$04;//3
      mov esi, dword ptr [edx].TInt64zahl.zahl;// 4

      test edi,$80000000;
      jz @@weiter2;
      inc eax;
      not edi;  //Vorzeichen ändern von Zahl2
      not esi;
      add esi,$01;
      adc edi,$00;
    @@weiter2:

      push eax;//ist ingewissermaßen das Vorzeichen

      mov eax,ebx; //2
      mul eax,esi; //2 * 4
      push eax;  //24 low direkt fertig
      mov ebp,edx; // 24 high nach ebp

      mov eax,ebx; // 2 dadurch ist ebx jetzt frei
      mul eax,edi; // 2 * 3

      add ebp,eax; // 24 high + 23 low
      adc edx,$00;//in edx = 23 high plus Übertrag aus 24 high + 23 low kein weiterer Übertrag Begründung:
                  //max (2^32-1) * (2^32-1) = 2^64- 2*2^32 +1 =
                  //oder $FFFFFFFF * $FFFFFFFF = edx = $FFFFFFFE und eax = $00000001
      mov ebx,edx;//23 high

      mov eax,ecx; //1
      mul eax,esi; // 1*4 esi ist jetzt auch frei

      add ebp,eax;//(in ebp 24 high + 23 low) + 14 low => fertig
      push ebp;//speichern
      adc ebx,edx;// 14 high + 23 high Überlauf (in ebp 24 high + 23 low) + 14 low
                  //adc edx,$00 kann nicht überlaufen aber mit ebx schon => esi
      xor esi,esi;
      adc esi,$00;//nur der Übertrag für 13

      mov eax,ecx;//1
      mul eax,edi;//1 * 3

      add eax,ebx;//13 low + [14 high + 23 high + Überlauf ((24 high + 23 low) +14 low)] 

      adc edx,esi;//Überlauf für 13 + 13 high + neuer Überlauf
      jnz @@viererBigint;

      cmp eax,$00;
      jnz @@dreierBigint;
    //wenn jetzt auch noch das erste Bit des schon gepushten Null ist ist eine Int64 darstellung Möglich
    //ob die bei dieser Zahlengröße noch angebracht ist ist fraglich aber zumindest passt es
      mov edx,[esp];//zweites Quadrupel
      test edx,$80000000;
      jnz @@zweierbigint;
      //int64
      //edx höherwertiges
      mov eax,[esp+$04];
      mov ecx,[esp+$08];//das Vorzeichen wenn bit 0 und 2 positiv 1 negativ
      test ecx,$01;
      jz @@novorzeichenswitch;
      not eax;
      not edx;
      add eax,$01;
      adc edx,$00;
    @@novorzeichenswitch:
      mov [esp+$04],edx;
      mov [esp],eax;

      mov dl, $01;
      mov eax, algebra.TInt64zahlclasszeiger;
      call TInt64zahl.create;
      jmp @@out;
    @@zweierbigint:
      mov ecx,$02;//länge des arrays zahl für Standardconstructor
      mov edx,$01;
      mov eax, algebra.TBigintzahlclasszeiger;
      call TBigintzahl.create;

      mov ecx,[esp+$08];//das Vorzeichen wenn bit 0 und 2 positiv 1 negativ
      and ecx,$01;
      mov byte ptr [eax].TBigintzahl.vorzeichen, cl;

      mov edx,[eax].TBigintzahl.zahl;

      mov ecx,[esp];
      mov [edx+$04], ecx;
      mov ecx, [esp+$04];
      mov  [edx], ecx;

    @@dreierbigint:
      mov ebp,eax;
      mov ecx,$03;//länge des arrays zahl für Standardconstructor
      mov edx,$01;
      mov eax, algebra.TBigintzahlclasszeiger;
      call TBigintzahl.create;

      mov ecx,[esp+$08];//das Vorzeichen wenn bit 0 und 2 positiv 1 negativ
      and ecx,$01;
      mov byte ptr [eax].TBigintzahl.vorzeichen, cl;

      mov edx,[eax].TBigintzahl.zahl;

      mov [edx+$08],ebp;  //array schreiben
      mov ecx,[esp];
      mov [edx+$04], ecx;
      mov ecx, [esp+$04];
      mov  [edx], ecx;


    //hardwware types???

      jmp @@out;

    @@viererbigint:
    
      mov esi,edx;
      mov ebp,eax;
      mov ecx,$04;//länge des arrays zahl für Standardconstructor
      mov edx,$01;
      mov eax, algebra.TBigintzahlclasszeiger;
      call TBigintzahl.create;

      mov ecx,[esp+$08];//das Vorzeichen wenn bit 0 und 2 positiv 1 negativ
      and ecx,$01;
      mov byte ptr [eax].TBigintzahl.vorzeichen, cl;

      mov edx,[eax].TBigintzahl.zahl;

      mov [edx+$0C],esi;
      mov [edx+$08],ebp;  //array schreiben
      mov ecx,[esp];
      mov [edx+$04], ecx;
      mov ecx, [esp+$04];
      mov  [edx], ecx;



    @@out:
      mov ebp,[esp+$0C];
      mov edi, [esp+$10];
      mov esi,[esp+$14];
      mov ebx, [esp+$18];
      add esp,$1C;
end;
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Mo 11.09.06 21:59 
user profile iconAllesquarks hat folgendes geschrieben:
Richtig ich weiß ja auch welchen ich aufrufen möchte bei call TBigintzahl.create nimmt er nur immer den ersten in der Liste.
Ach so, das Overloading selbst ist dein Problem?! Sorry, stand ein wenig auf dem Schlauch. :-?

Allesquarks hat folgendes geschrieben:
Compilermagic ich hoffe nicht denn ich ruf an sehr vielen stellen über dl,$01; und eax Klassenreferenz den Constructor auf funktioniert bisher auch einwandfrei.
Kommt drauf an, wie du ihn aufrufst.
Wenn du hier ein wenig runterscrollst, siehst du ein Beispiel für das Erzeugen von Objekten in Assembler. Sieht so aus, als würde die Compiler-Magic, die ich beim Aufruf erwartet habe (nämlich das Reservieren des Speichers), in Wirklichkeit in die Funktion selbst gesteckt wird. Hach, was ist C++ doch schön :mrgreen:

Allesquarks hat folgendes geschrieben:
Stehen denn auch die nicht virtuallen Methoden in der VMT. Nun ja eigentlich logisch, da die Klassen ja darüber identifieziert werden.
Eine VMT ist nichts, was irgendwie standardisiert oder vorgeschrieben ist (außer bei COM-Objekten). Es ist einfach eine gängie Art und Weise, Objektorientierung praktisch zu implementieren. Ob nun nur die virtuellen Methoden oder alle Methoden in eine Tabelle wandern, die mit jedem Objekt verknüpft ist, ist implementationsabhängig. Wenn Delphi es so macht könnte FreePascal oder GNU Pascal es schon wieder ganz anders machen ("könnte" ist wörtlich zu nehmen, zumindest FreePAscal erhebt den Anspruch, zu Delphi vollständig kompatibel zu sein).

Allesquarks hat folgendes geschrieben:
Bin gerade auf Turbo Delphi umgestiegen. Auch da funktioniert es nicht.
Hätte mich auch schwer gewundert, wenn Borland interne Strukturen geändert hätte, ohne daß dies durch hinzugefügte Features notwendig geworden wäre. Overloading wird in Delphi allein durch den Compiler aufgelöst, nicht durch den Assembler. Das ließe sich anders machen, der G++ (C kennt kein Function Overloading) jagt zum Beispiel seine Symbole durch ein Name-Mangling und erzeugt so eindeutige Symbole, die im Assembler verwendet werden. Wieder andere Compiler für andere Sprachen können es wieder anders machen (wobei mir außer Auflösung im Compiler und Auflösung im Assembler nicht mehr so viele Möglichkeiten einfallen, das zu realisieren :mrgreen:).

Allesquarks hat folgendes geschrieben:
Vielen Dank nochmal auch dass einem hier versucht wird zu helfen, wenn man es auch selber lösen kann.
Wieso sollte man nicht? :gruebel:

user profile iconBenBE hat folgendes geschrieben:
Versuche einmal den Ansatz, den ich oben für normale Prozeduren vorgeschlagen hab ...

ausblenden Delphi-Quelltext
1:
var Create1 : Procedure (vorzeichen:boolean;zahl:int64) of object = TBignumint.Create;					
Da TBignumint kein object ist, kann TBignumint.Create keine procedure of object sein, da hatte eer nämlich auch schon ausprobiert ;-)

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert