![]() |
[ASM] Dividieren von Ganzzahlen
Ja, ihr hab richtig gelesen, diesmal gehts um Assembler. Meine ersten Erfahrungen (ASM betreffend) liegen ein paar Monate zurück, wegen einem Bekannten bin ich heute wieder dazu gekommen ein bisschen mehr herumzuspielen. Ich habe derzeit ein kleines Problem, und zwar mit dem Dividieren von zwei Ganzzahlen. Bei der Multiplikation mach ich des ja einfach so:
Delphi-Quellcode:
Deshalb vermutete ich das Dividieren verläuft ähnlich, folgendes habe ich versucht:
procedure TForm1.Button1Click(Sender: TObject);
var test : Integer; begin test := 7; asm MOV EAX,test // <- lese test ein IMUL EAX, 5 // <- multipliziere mit 5 MOV test, EAX //<- schriebe Wert zurück in test end; ShowMessage(IntToStr(test)); end;
Delphi-Quellcode:
Egal ob ich IDIV oder ein normales DIV nehme, als Ergebnis erhalte ich 5. 20 durch 5 ist bei mir aber 4, wieso bekomme ich dort 5 heraus? Bitte nehmt Rücksicht, bin absoluter Assembler-Anfänger. :oops: Irgendwie steh ich gerade ziemlich auf dem Schlauch, weiß jemand was da los ist? Danke euch.
procedure TForm1.Button1Click(Sender: TObject);
var test : Integer; begin test := 20; asm MOV EAX,test // <- lese test ein MOV BH, 5 // <- teile BH 5 zu IDIV BH // <- dividiere durch 5 MOV test, EAX //<- schriebe Wert zurück in test end; ShowMessage(IntToStr(test)); end; |
Re: [ASM] Dividieren von Ganzzahlen
Also bei mir kommt 4 raus.
|
Re: [ASM] Dividieren von Ganzzahlen
Ja, wie ich bemerkt hatte kommt wirklich 4 raus. :wall: Der Quellcode in diesem Thread war nur ein Auszug, ich hab gerade erst gesehen ich hatte aus Versehen noch ein INC EAX weiter unten mit drin, deshalb kam eins mehr heraus. :wall:
Ich bitte um Verzeihung und glaube ich schalte den PC jetzt lieber aus. :cry: |
Re: [ASM] Dividieren von Ganzzahlen
Hallo Balu,
hast du einmal versucht, mit deinem Code 21 durch 5 zu teilen? Hier ist die ![]() Gruß Hawkeye |
Re: [ASM] Dividieren von Ganzzahlen
Hallo Hawkeye,
jupp versucht habe ich es, es kommt ein Ergebnis raus das garantiert nicht stimmt. Ich versuch mich mal da einzulesen und eine Lösung zu finden, danke für den Link. :thumb: Wie gesagt ich bin noch Anfänger und die Materie ist nicht sonderlich leicht verständlich. ;) |
Re: [ASM] Dividieren von Ganzzahlen
Delphi-Quellcode:
Das Problem ist, daß Du durch BH dividierst.
procedure TForm1.Button1Click(Sender: TObject);
var test : Integer; begin test := 20; asm MOV EAX,test // <- lese test ein MOV BH, 5 // <- teile BH 5 zu IDIV BH // <- dividiere durch 5 MOV test, EAX //<- schriebe Wert zurück in test end; ShowMessage(IntToStr(test)); end; Dann wird AX (die unteren 2 Bytes von EAX) durch BH geteilt. Der Quotient kommt in AL, der Modulo in AH. Benutze als Divisor ECX (EBX sollte nie verändert werden) als Divisor. Dann kommt der Quotient in EAX, der Modulo in EDX Also
Delphi-Quellcode:
mov eax,test
cdq mov ecx,5 idiv ecx mov test,eax |
Re: [ASM] Dividieren von Ganzzahlen
Hallo,
funktioniert gut diese Lösung, danke. :thumb: Aber sagmal was macht denn der Befehl "cdq", von dem hab ich bis jetzt noch gar nichts gehört? :gruebel: |
Re: [ASM] Dividieren von Ganzzahlen
cdq macht folgendes:
Wenn das Vorzeichenbit von eax gesetzt ist, wird edx auf 0xFFFFFFFF gesetzt, ansonsten auf 0x00000000. |
Re: [ASM] Dividieren von Ganzzahlen
Aha, danke.
Gibt es eigentlich irgendwo eine Tabelle wo kurz die wichtigsten Befehle mit kurzer Beschreibung aufgelistet sind? |
Re: [ASM] Dividieren von Ganzzahlen
Du könntest dir das Prozessorhandbuch von Intel ansehen. Ansonsten einfahc mal googeln.
|
Re: [ASM] Dividieren von Ganzzahlen
Örm, falsch.
x86 Instruction Set Reference CWD/CDQ—Convert Word to Doubleword/Convert Doubleword to Quadword Description Doubles the size of the operand in register AX or EAX (depending on the operand size) by means of sign extension and stores the result in registers DX:AX or EDX:EAX, respectively. The CWD instruction copies the sign (bit 15) of the value in the AX register into every bit position in the DX register (see Figure 7-6 in the IA-32 Intel Architecture Software Developer’s Manual, Volume 1). The CDQ instruction copies the sign (bit 31) of the value in the EAX register into every bit position in the EDX register. The CWD instruction can be used to produce a doubleword dividend from a word before a word division, and the CDQ instruction can be used to produce a quadword dividend from a doubleword before doubleword division. The CWD and CDQ mnemonics reference the same opcode. The CWD instruction is intended for use when the operand-size attribute is 16 and the CDQ instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when CWD is used and to 32 when CDQ is used. Others may treat these mnemonics as synonyms (CWD/CDQ) and use the current setting of the operand-size attribute to determine the size of values to be converted, regardless of the mnemonic used. Sprich: es füllt EDX mit Sign(EAX). @Balu: Intel x86 Instruction Set Reference - Google mal danach ;) |
Re: [ASM] Dividieren von Ganzzahlen
Habe ich das nicht gesagt?
|
Re: [ASM] Dividieren von Ganzzahlen
Zitat:
/EDIT: Mitten im POST ein Discon... *grml* |
Re: [ASM] Dividieren von Ganzzahlen
Zitat:
Zitat:
Würde CDQ EDX mit Sign(EAX) füllen, dann wäre EDX, je nach Interpretation von "Sign(EAX)", entweder $80000000 oder $00000001 oder $00000000 Richtig ist, daß CDQ Bit 31 aus EAX in jedes Bit von EDX kopiert also ist EDX dann entweder $FFFFFFFF oder $00000000, also exakt so, wie 3_of_8 es schrieb. |
Re: [ASM] Dividieren von Ganzzahlen
Ach verdammt, ich hab statt edx da oben eax gelesen :oops: Und beim schreiben nich gedacht :wall: Ich meinte, das Sign(EAX) in jedes Bit geschrieben wird, nicht ins ganze Register...
*jetzt besser die klappe hält* |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:25 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