multiplizieren ohne mul
-
hallo leute..
ich hätte eine frage... irgendwie komme ich mit meinem programm nicht weiter...
ich soll zwei ganze positive Zahlen über die Tastatur eingeben und die miteinander multiplizieren.
die zweite zahl soll eine Zweierpotenzzerlegung sein.....
das ganze soll ohne den befehl mul passieren..
ich wollte das mit dem carry flag machen, aber weiß jetzt nicht wirklich wie ich das anstellen soll..
wäre für jede hilfe sehr dankbar..
mfg
-
mov eax,1234 mov edx,3 ; IN: eax and edx ; OUT: edi::esi (64bit) xor esi,esi xor edi,edi xor ecx,ecx mov ebx,1 @1: test edx,ebx jz @skip add esi,eax adc edi,ecx @skip: shl eax,1 jz @fin lea ecx,[ecx*2] lea ebx,[ebx*2] adc ecx,0 jmp @1 @fin: ; edi::esi = result
-
ein kleiner Fehler hat sich eingeschlichen
:
; IN: eax and edx ; OUT: edi::esi (64bit) push 32 xor esi,esi xor edi,edi xor ecx,ecx mov ebx,1 @1: test edx,ebx jz @skip add esi,eax adc edi,ecx @skip: shl eax,1 lea ecx,[ecx*2] lea ebx,[ebx*2] adc ecx,0 dec DWORD ptr [esp] jnz @1 add esp,4 ; edi::esi = result
-
masm schrieb:
mov eax,1234 mov edx,3 ; IN: eax and edx ; OUT: edi::esi (64bit) xor esi,esi xor edi,edi xor ecx,ecx mov ebx,1 @1: test edx,ebx jz @skip add esi,eax adc edi,ecx @skip: shl eax,1 jz @fin lea ecx,[ecx*2] lea ebx,[ebx*2] adc ecx,0 jmp @1 @fin: ; edi::esi = result
wäre echt nett wenn du ein paar wörter oder sätze schreiben könntest..
-
all zu einfach sollte man es dir dann aber auch nicht machen
Bsp: 5 * 1234 5 = 1*2^0 + 0*2^1 + 1*2^2 5 * 1234 = (1*2^0 + 0*2^1 + 1*2^2)*1234 = 1*2^0*1234 + 0*2^1*1234 + 1*2^2*1234 1*2^0*1234 = 1234 SHL 0 = 1234 0*2^1*1234 = 0 1*2^2*1234 = 1234 SHL 2 = 4936 ------------------------------- 6170
masm
-
du erwartest echt viel
ich verstehe die hälfte ja garnich... also shl kenn ich
aber was ist ein esi und edi und eax und und und
-
sry - bin einfach da von ausgegangen, das du das für einen x86-32-Prozessor schreibst. Wenn du aber esi,edi,eax (Register) nicht kennst, gehe ich mal davon aus, das du eine andere Archetektur verwendest?
-
hmm also bin jetztn bissel verwirrt
ich schreib in 8086 die sachen..
ich kennaber als register nur ax,bx,cx und dx...
-
ohne eine Möglichkeit es zu testen:
mov ax,1234 mov dx,5 push 32 ; IN: ax and dx ; OUT: di::si (32bit) xor si,si xor di,di xor cx,cx mov bx,1 @1: test dx,bx jz @skip add si,ax adc di,cx @skip: shld cx,ax,1 shl cx,1 shl bx,1 dec WORD ptr [sp] jnz @1 add sp,4 ; di::si = result
-
o gott...
-
wenn man ohne den mul befehl multiplizieren will, dann entweder per addition oder per bitverschiebung.
also 5 * 8 in bit:0101b * 1000b -> 5 * 2^3 ->5 um drei stellen nach Links verschieben (z.B. mit shl reg,3)
->0010 1000b -> 28h -> 40d
per addition:
5 nach register1
8 nach register2
z.Bmov ax,8 mov cx,5 add ax,ax loop ; Befehl loop orientiert sich am cx register und vermindert dabei cx um 1 pro schleife
(einmal zuviel adddiert, muss noch korrigiert werden)
-
nachtfeuer schrieb:
mov ax,8 mov cx,5 add ax,ax loop ; Befehl loop orientiert sich am cx register und vermindert dabei cx um 1 pro schleife
(einmal zuviel adddiert, muss noch korrigiert werden)
Du brauchst noch ein drittes Register zur Aufnahme des Ergebnisses und 'ne Sprungmarke.
Dein Beispiel muss auch funktionieren!
-
aber hallo schrieb:
Du brauchst noch ein drittes Register zur Aufnahme des Ergebnisses und 'ne Sprungmarke.
Dein Beispiel muss auch funktionieren!Man braucht kein drittes Register zur Aufnahme des Ergebnisses, das sieht man an dem Beispielcode, und der sollte auch nur die Additionsweise darstellen, mehr nicht.
-
nachtfeuer schrieb:
Man braucht kein drittes Register zur Aufnahme des Ergebnisses, das sieht man an dem Beispielcode
natürlich - 8*5 ergibt 40 und nicht, wie deinem 'Beispiel', 256
-
^^ hab nicht mehr so viel plan, und in meiner aubildung nur auf 8080 gearbeitet.
Hab nur mal aus langeweile Thema überflogen, und man versucht ja zu helfen...
Aber sollte das ergbnis nicht in ax normal drin stehen?EDIT: mit 8085...
-
das ist mein bisheriger quellcode...da ist aber nochn fehler drin... bin ich auf dem richtigen weg ?
.model small include macros.mac .stack 100h .data text1 db "Geben Sie die erste Zahl ein: ", 10,13, "$" text2 db "Geben Sie die zweite Zahl ein: ", 10,13, "$" text3 db "Das Ergebnis lautet: ",10,13, "$" .code start: mov ax,@data mov ds,ax mov dx, OFFSET text1 mov ah,09h int 21h readZ bx mov dx, OFFSET text2 mov ah,09h int 21h readZ dx xor ax,ax schl1: shl bx,1 jne schl1 shr dx,1 jnc schl2 add ax,bx jc schl2 schl2: shl bx,1 add ax,bx mov dx, OFFSET text3 mov ah,09h int 21h mov ax,4c00h int 21h end start
-
cookielein schrieb:
das ist mein bisheriger quellcode...da ist aber nochn fehler drin... bin ich auf dem richtigen weg ?
Das ist für mich noch nicht so recht ersichtlich. Vielleicht wäre ein wenig Doku hilfreich, was du dir wie dabei gedacht hattest. Du brauchst auch nicht den ganzen Code zu posten, es reicht eigentlich das zur Lösung anwendbare Prinzip.
(und jc zur nächsten Befehlsadresse (jc schl2) kann z.B. auch weglassen)
Darf ich fragen, mit welchem Debugger du arbeitest?
-
ich arbeite mit dem tasmx
ok also
ich habe einen bx und einen dx register und mein ergebnis soll im ax register ausgegeben werden.
ich sag jetzt mal als beispiel hab ich im bx register eine 2 eingetippt und im dx eine 4.
im bx benutze ich shl also multiplizere ich mit einer 2 und gleichzeitig benutze ich im dx register shr also dividiere ich durch 2. das mach ich so lange bis dx 0 ist. am ende addiere ich mein bx register mit dem ax...ich weiß aber auch das es bei anderen zahlen anders aussehen kann..zb 5*5
also wenn im bx und dx eine 5 steht. beim multiplizieren ist alles ok aber wenn ich durch 2 teile kriege ich bei dem ersten 2,5 raus und da wird "der rest" in den carry flag geschrieben bzw. wird cf 1. da müsste ich erstmal meinen bx register mit ax addieren und dann die ganzen schritte wieder durchgehen am ende wird bx wieder zu ax, mit dem wert der schon drin ist ( in dem fall die 5) addiert.o gott...ich hoffe es ist einigermaße verständlich...
-
cookielein schrieb:
o gott...ich hoffe es ist einigermaße verständlich...
naja, man ahnt schon...z.B 5 -> 0101 * 0111 -> 7 -> dx
man testet nun die 7 in dx auf CarryFlag bzw. auf gesetztes bit
und im Ganzen testet man nach Shift nach Rechts, ob dx schon auf 0 geshiftet wurde.Wie im Handschriftlichen, wird je nachdem, wo man anfängt, die Rechnung nach jedem Schritt einmal nach links bzw. nach rechts versetzt. Handschriftlich wird in der Regel von rechts nach links gerechnet, also verschieben wir nach jeder Rechnung das Zwischenergebnis um eine Stelle nach links, diese Aufgabe übernimmt bx
Für Zwischenergebnisse und Endergebnis muss ax herhalten.Hier ein Vorschlag, dx am Anfang prüfen und die Addition bei 0*x einfach überspringen - trotzdem muss vorgeschoben werden:
1AA4:0100 09D2 OR DX,DX 1AA4:0102 740A JZ 010E 1AA4:0104 D1EA SHR DX,1 ;Von hinten... 1AA4:0106 7302 JNC 010A ;tatsächlich stand da JAE, aber gibt man jae ein... 1AA4:0108 01D8 ADD AX,BX ;wenn CY gesetzt, dann 1 * X 1AA4:010A D1E3 SHL BX,1 ;und X um eine Stelle nach links verschiebn 1AA4:010C EBF2 JMP 0100 1AA4:010E CD20 INT 20
man sollte aber wenigstens noch xor ax,ax vorher machen, wie du es ja auch schon gemacht hast...;)
-
ok also erstmal danke für deine hilfe..
irgendwie bin ich aber nicht mehr aus dieser aufgabe schau geworden und hab mir eine andere aufgabe geschnappt... mit dieser werde ich mich nochmal auseinandersetzen müssen...obwohl ich es verstehe kann ich noch nicht ganz umsetzen...
ich meld mich wenn ich bisschen weitergekommen bin
danke nochmal