multiplizieren ohne mul



  • 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
    

Anmelden zum Antworten