![]() |
Delphi Inline Assembler, größere Register
N'abend!
Habe mich gerade eben mal an das Inline Assembling von Delphi getraut. Hat mich zuerst abgeschreckt, aber wenn man erstmal hinter den Grundgedanken kommt, ist es einfacher als man erwartet. Nun, ich habe mir vorgenommen, eine Funktion zur berechnung der Fakultät zu schreiben. Klappt soweit auch ganz gut. Jedoch ist natürlich irgendwann der Wertebereich überschritten, hier leider schon ab 14! . Wie kann ich die Größe der Register ändern? Mit CDQ habe ich es bereits getestet, half aber leider auch nicht. Grüße, Frank.
Delphi-Quellcode:
function faculty(i:integer):integer;
asm mov ecx,i //schleifenvariable auf i setzen mov eax,1 //startwert auf 1 initialisieren @schleife: //wiederhole mul ecx //eax = eax * schleifenvariable loop @schleife //bis schleife i mal durchlief mov @result,eax //gebe ergebnis aus end; |
Re: Delphi Inline Assembler, größere Register
Du könntest 2 (32 Bit) Register nehmen nach der Art: 2 Byte = 1 Word, 2 Word = 1 DWord, 2 DWord = 1 QWord, etc um damit die Größe der Register zu potenzieren. Dann hast du allerdings bei 2 gebrauchten Registern eins weniger, was du sonst verwenden könntest ..
|
Re: Delphi Inline Assembler, größere Register
Das klingt gut, allerdings habe ich keinen Schimmer, wie ich da rangehen könnte. Welche Befehle werden mir da nützlich sein? Oder hast du gar ein praktisches Beispiel zur Hand?
Grüße. |
Re: Delphi Inline Assembler, größere Register
Zitat:
Die Addition und Subtraktion mit 32:32 Registern ist recht einfach (add+adc bzw. sub+sbb). Für eine Multiplikation ist schon mehr notwendig. Da schaust du dir am besten mal die _llmul Funktion in der System.pas an. Du könntest diese natürlich auch aufrufen. Ach ja: Schau dir mal deinen Assemblercode in der CPU-Ansicht des Debuggers an. Da werden dir sicherlich ein paar Dinge auffallen (z.B. "mov eax,eax"). |
Re: Delphi Inline Assembler, größere Register
Einiges kann man auch noch mit den MMX-Registern anfangen, welche jeweils 64-Bit klein sind
(unterstützt ja nahezu jede aktuelle CPU) hier noch einiges zu Registern:
Code:
ja und Result liegt bei Delphi (mindestens) in EAX
Register welche nicht verändert werden dürfen (z.B. per PUSH/POP sichern):
ESP EBP EDI ESI EBX Register: 8-Bit: AL(EAX), AH(EAX), BL(EBX), BH(EBX), CL(ECX), CH(ECX), DL(EDX), DH(EDX) 16-Bit: AX(EAX), BX(EBX), CX(ECX), DX(EDX), SI(ESI), DI(EDI), BP(EBP), IP(EIP), SP(ESP) 32-Bit: EAX, EBX, ECX, EDX, ESI, EDI, EBP, EIP, ESP 80-Bit: ST[0], ST[1], ST[2], ST[3], ST[4], ST[5], ST[6], ST[7] 64-Bit: MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7 // MMX-Register weiterte: XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, CR0, CR2, CR3, CR4, DR0, DR1, DR2, DR3, DR6, DR7 Parameterübergabe: EAX EDX ECX PUSH(EBP + x) ... PUSH(EBP + 8) PUSH(EBP + 4) // Parameter1, Parameter2 ... EAX PUSH(EBP + 4, EBP + 8) EDX // 64-Bit Werte werden immer gepuscht z.B. Parameter 1, 2, 3 |
Re: Delphi Inline Assembler, größere Register
Im Grunde ist der Teil mit: "wir schreiben das in Assembler" hier das eigentliche Problem. Zumindest wenn man sich deine Aufgabenstellung ansieht. Versuch's mal mit nem Taschenrechner. Die meisten bleiben irgendwo um 30! stecken, neuere irgendwo unter 60! und vielleicht gibt es auch noch Ausnahmen. Das Problem ist weniger die Geschwindigkeit der Berechnung (und das wäre der einzige Grund Assembler einzusetzen), als vielmehr der Platz zum Speichern der Zwischenergebnisse. Und da die Register bis zu absehbaren Größen eben nicht mehr ausreichen, bleibt wohl nur noch der "langsamere" RAM.
Beispielsweise wie hier: ![]() Auf der verlinkten Webseite findet man: Example: Binary multiplication This program multiplies two 8-bit unsigned numbers using a shift and add algorithm to generate a 16-bit product. The multiplier is in D2 and the multiplicand in D1. The product is returned in D1. Algorithm: Start with most significant bit of multiplier, i.e. bit = 8. Shift product to line up properly (product = 2 * product). If multiplier[bit] = 1 then product = product + multiplier. Decrement bit. If bit>=0 then goto 2. Functional specification (pseudocode):
Code:
MULTIPLICAND 8-bit number to be multiplied
MULTIPLIER 8-bit number that MULTIPLICAND is multiplied by PRODUCT 32-bit result PRODUCT = 0; /*clear PRODUCT*/ BIT = 8; /* starting at MSB */ FOR j = 1 TO 8 DO /*do for each bit of MULTIPLIER*/ BEGIN PRODUCT = PRODUCT * 2; /*shift PRODUCT left by one bit*/ IF MULTIPLIER[9-bit] = 1 THEN PRODUCT = PRODUCT + MULTIPLICAND; /* do calculations from most significant bit to least significant bit */ BIT=BIT-1; /* decrement bit */ END |
Re: Delphi Inline Assembler, größere Register
Hey super! Das wird mich mit sicherheit ein Stückchen weiterbringen. Später zumindest, muss jetzt erstmal in die Schule ;)
Zitat:
|
Re: Delphi Inline Assembler, größere Register
Zitat:
Zitat:
Was ich meinte ist, daß man immer die Mittel, welche man zum Lösen einer Aufgabe/eines Problems einsetzt, gut abwägen muß. Assembler kann ab und an eine feine Sache sein, kann aber auch die Lösung erschweren. Und zumindest Optimierung ist heute kein gutes Argument mehr für Assembler, es sei denn du kennst die Manuals aller Prozessorhersteller auswendig, hast die Timings in allen möglichen Situationen (Stichwort: Prefetching) im Kopf ... etc. pp. Compiler, so sie denn nicht vom Prozessorhersteller selbst entwickelt werden/wurden, machen heutzutage ausgewogene Optimierungen um auf verschiedenen Prozessoren gute Laufzeiten zu erreichen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz