multiplizieren ohne mul
-
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
-
cookielein schrieb:
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...
also, keine Ursache für das Dankeschön
Aber darf ich vielleicht fragen, wo die Schwierigkeiten genau liegen. Am Anfang ist es normal bei Assembler, dass man relativ viele Fehler macht. Aber das gibt sich mit der Zeit.
Ich finde, du machst die Sache schon sehr gut, nach meinem Eindruck fehlt wirklich nur etwas Debugging-Praxis. Und du bist auch nicht der einzige, dem die Umsetzung der Lösung schwerfällt, selbst masm als erfahrener Assemblerprogrammierer hatte bei dieser Aufgabe seine Schwierigkeiten.zur Sicherheit hast du hier nochmal eine korrigierte Fassung des masm-Vorschlags Die Linksverschiebung über 16bit hinaus wird mit einem 2. Register gemacht. Auch die Zwischensumme braucht bei größeren Zahlen ein zweites Register:
;IN: AX und DX OUT: SI und DI bzw. Ergebnis in DI:SI ; Registerweiterung für AX ist CX 1B11:0100 B83412 MOV AX,1234 1B11:0103 BAFF00 MOV DX,00FF ;größerer Wert zum Testen für 32bit Ergebnisse 1B11:0106 6A16 PUSH +16 ;Unser Zählwerk: 16 Bit reicht (die Variante mit Shr und or hätte auch gereicht) 1B11:0108 89E5 MOV BP,SP ;wir kopieren den Stackpointer(SP) und navigieren im Stack mit BP 1B11:010A 31F6 XOR SI,SI ;SI = 0 1B11:010C 31FF XOR DI,DI ;SI 32bit Erweiterung = 0 1B11:010E 31C9 XOR CX,CX ;AX 32bit Erweiterung = 0 1B11:0110 BB0100 MOV BX,0001 ;Nulltester 1B11:0113 85DA TEST DX,BX ;AND Operation, aber es werden nur Flags verändert 1B11:0115 7407 JZ 011E ;Nullen überspringen die Addition (aber nicht die Linksverschiebung) 1B11:0117 01C6 ADD SI,AX ;1 * X und Zwischensumme 1B11:0119 83D700 ADC DI,+00 ;falls Übertrag 1B11:011C 01CF ADD DI,CX ;Übertrag der Linksverschiebung von AX auch hierhin 1B11:011E D1E1 SHL CX,1 ;zuerst die Erweiterung einen Schritt nach links 1B11:0120 D1E0 SHL AX,1 ;10er, 100er, 1000er... 1B11:0122 83D100 ADC CX,+00 ;Übertrag beim Linksverschieben mit Carryflag 1B11:0125 D1E3 SHL BX,1 ;der Nulltester geht zum nächsten Bit 1B11:0127 FE4E00 DEC BYTE PTR [BP+00] ;unser Hauptzählwerk zählt einen nach unten 1B11:012A 75E7 JNZ 0113 ;und springt zurück zur Ausgangsposition 1B11:012C 83C502 ADD BP,+02 ;Unser Stack-Navigiergerät zurückstellen 1B11:012F 89EC MOV SP,BP ;Stackzeiger zurücksetzen 1B11:0131 90 NOP 1B11:0132 90 NOP ;Breakpoints 1B11:0133 90 NOP 1B11:0134 CD20 INT 20 ;Programmende, aber das brauchen wir hier nicht ;man lässt das Programm (im Debugger) bis zum Breakpoint laufen, und schaut sich die Register ;an. ;Man testet nach Möglichkeit auch Grenzfälle aus, wie AX = 0 oder FFFF und DX = 0 oder FFFF oder 7FFF 8000 oder AAAA und so weiter
-
ich muss mich mit diesem code auseinandersetzen und ich muss mal sehen wann ich zeit dazu finde
eine kleine korrektur : ich bin nicht die einzige dem das schwer fällt... jaaa das ist mir klar..ich find auch das assembler schwer ist aber mit der zeit kann man es wirklich lernen..
naja.. ich werd mich in den nächsten tagen wieder melden
-
mal eine ganz blöde frage muss ich wenn ich readz benutze auch writez benutzen ?
ich weiß das readz nur die zahl in binär umwandelt aber ich bin grad total verwirrt und komm nicht mehr aus der sache raus..
hab mir jetzt wieder meine gedanken aufgeschrieben, ich weiß auch ungefähr was ich benutze aber ich hab keine ahnung wie ich das mache-.-wäre echt nett von mir jemand mal kurz unter die arme greifen könnte..
-
Wenn du uns noch schreiben koenntest, was diese Macros ueberhaupt tun, haettest du dir wahrscheinlich schon selbst geholfen.
So kann ich allerdings auch nur raten:
Wenn "readz" eine Dezimalzahl von der Konsole als Integer (Ganzzahl) in ein uebergebenes Register einliest, liegt die Vermutung nahe, dass "writez" als passendes Gegenstueck eine Ganzzahl in einem uebergebenen Register wieder im Dezimalformat in die Konsole schreibt...
-
ok also ich habs nochmal bearbeitet und diesmal auch kommentiert
aber es ist immer noch ein fehler drin....
ich glaube langsam es ist nicht nur 1 fehler...
.model small include macros.mac .stack 100h .data ;anfang des datensegments ;Einleitung db "Bitte geben Sie zwei positive Zahlen ein", 10,13, "$" 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 ;anfang des codesegments start: mov ax,@data ;daten aus dem datensegment in ax laden mov ds,ax ;datensegment laden mov dx, OFFSET text1 ;ausgeben des textes mov ah,09h int 21h readZ dx mov dx, OFFSET text2 ;ausgeben des zweiten textes mov ah,09h int 21h readZ bx ;einlesen von bx xor ax,ax ;loesche ax register schl2: shl bx,1 ;bxnach links schieben jnc schl2 ;wenn carry 0 springe zuruck zu schl2 shr dx,1 ; dx nach rechts schieben jnc schl2 ; wenn carry 0 springe zuruck zu schl2 mov dx, OFFSET text3 ;ausgeben des dritten textes mov ah,09h int 21h add ax,bx ;addiere ax und bx jmp ende ;springe zum ende ende: mov ax,4c00h int 21h end start
-
fertiiiiissschhhh
habs doch hinbekommen
ich bin ganz schön stolz auf mich
danke trotzdem an alle
-
Hallo du könntest ja mal zeigen was nun letzendlich die Lösung war.
Vielleicht sucht irgendwann nochmal jemand nach so etwas.
-
gerne :))
.model small include macros.mac .stack 100h .data ;anfang des datensegments ;Einleitung db "Bitte geben Sie zwei positive Zahlen ein", 10,13, "$" 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 ;anfang des codesegments start: mov ax,@data ;daten aus dem datensegment in ax laden mov ds,ax ;datensegment laden mov dx, OFFSET text1 ;ausgeben des textes mov ah,09h int 21h readZ dx push dx mov dx, OFFSET text2 ;ausgeben des zweiten textes mov ah,09h int 21h readZ bx ;einlesen von bx pop dx xor ax,ax ;loesche ax register mov cx,0 schl2: shr bx, 1 ;bx nach rechts schieben jnc ohnebit ;wenn carry 0 springe zuruck zu ohnebit shl dx, cl ;dx nach links schieben add ax, dx shr dx, cl add cx, 1 cmp cx, 16 jne schl2 ohnebit: add cx, 1 cmp cx, 16 jl schl2 writeZ ax mov ax,4c00h int 21h end start