2 Zahlen Addieren
-
Hallo ich versuche gerade mit TASM 2 Zahlen zu Addieren
Aber jetzt komme ich nicht weiter.
Das Ergebniss aus 7+3 ist ja 10 diese 10 wird in bh gespeichert.
Aber wie kann ich nun bh ausgeben ?Ich weiss nur wie ich z.b. aus Variablen mit
mov ah,9h
Text ausgeben kann aber wie das hier jetzt funktioniert hab ich leider kein Plan.
.model small .stack 100h .data .code entrypoint: mov ah,7 mov bh,3 add bh,ah end entrypoint end
-
Deine Frage ist ja reichlich wage formuliert. Also mal sehen:
Du benutzt wahrscheinlich (Borland) TASM, fuer den PC, um 16Bit RM DOS-Programme zu schreiben. Du weisst scheinbar, wie man "$"-Terminierte Strings mit Hilfe der DOS-Funktion 09 (ah=09h, int 21h) ausgibt. Nun willst du wissen, wie du eine vorzeichenlose Integer-Zahl in einen lesbaren String mit Ziffern umwandeln kannst, um sie mit zuvor genannter Funktion auf dem Schirm ausgeben zu koennen?int->string:
Das Prinzip ist eigentlich immer das Gleiche, egal, welche Zahlenbasis (binaer, oct, dec, hex...) du verwenden willst:
Dividiere deine Zahl wiederholt so lange durch die Basis (zB. 10 fuer dezimal), bis der Quotient 0 wird.
Der x86-Befehl "div" fuehrt eine Division von ax, ax:dx oder eax:edx durch den Operanden, den Divisor durch (je nachdem, ob dieser 8, 16 oder 32Bit breit ist) und speichert den Quotient in ax (al, ax oder eax) und den Rest in dx (ah, dx oder edx).Der Rest jeder Division ist dann eine Stelle der Zahl (hier Werte von 0-9). Die musst du noch in ein lesbares Zeichen umwandeln, zB. fuer ASCII, indem du 30h dazu addierst (oder "veroderst") - siehe eine Tabelle des ASCII-Zeichensatzes.
Bei diesem Vorgang kommen die Ziffern, wie du feststellen wirst, in umgekehrter Reihenfolge heraus, also zuerst die 1er-Stelle, dann 10er, usw.
Du kannst also nun deinen String entweder direkt mit den berechneten Resten von hinten noch vorn befuellen, oder du parkst die Ziffern auf einem Stapel und "pop"st sie von dort in deinen String, um die Reihenfolge umzudrehen. Dazu bietet es sich an, den normalen x86-Stack zu benutzen und mit zu zaehlen, wie viele Ziffern du raufpackst.
Am Ende noch das "$" an den String haengen und du kannst ihn mit Funktion 09h ausgeben.Natuerlich gibt es abhaengig von verschiedene Zahlen-Breiten, -Basen, und Zahl der Stellen noch verschiedenste Optimierungsmoeglichkeiten, aber das Prinzip ist wie gesagt das Gleiche.
Hoffe das ist so weit klar geworden; sonst nochmal genauer fragen.
-
Muss ich dann bh durch 10 dividieren ?
-
Das geht (zumindest mittels div) nicht.
Wenn du das Ergebnis der Addition, das ja in bh steht, ausgeben willst, musst du bh eben nach ax (Vorsicht, bh hat 8, ax 16Bit) kopieren. Dann klappt das mit der Division auch wie beschrieben.
-
Und was muss ich da jetzt wo dividieren ?
.model small .stack 100h .data ergebniss DB 2 .code entrypoint: mov ah,7 mov bh,3 add bh,ah mov ax,bh mov ah,9h int 21h mov ah,4ch int 21h end entrypoint end
-
Zuerst mal kannst du (wie ich angedeutet habe) ein 8Bit-Register (bh) nicht einfach per mov in ein 16Bit-Register (ax) kopieren. Wo soll die CPU auf diese Weise denn die fehlenden 8Bit herzaubern?
Vielleicht schaust du dir dazu erstmal an, wie die 8,16 und 32Bit-Register beim x86 zusammenhaengen: click
Dann mal kurz drueber nachdenken, wie man bh nach ax bekommt, wobei die oberen 8Bit von ax (ah) sinnvollerweise 0 gesetzt werden.
Es gibt auch hier mehr als eine Moeglichkeit - seit AFAIR dem 486er sogar einen extra Befehl: movzx
Mit diesem Befehl kannst du einfach Register geringerer Breite in Register groesserer Breite kopieren.Wie gesagt musst du dann die (16Bit-)Zahl, die du in Ziffern zerlegen willst (sie sollte in ax stehen), durch die Basis (10 fuer Dezimal-Zahlen) dividieren. Und zwar in einer Schleife, bis der Quotient 0 wird... habe ich auch schon geschrieben. Auf 0 pruefen kannst du allgemein mit dem Befehl cmp, oder bei Registern mit dem Befehl test. zB. "test al, al" setzt das Zero-Flag (zB. bedingte Spruenge jz/jnz), wenn al=0 ist.
div akzeptiert als Operand (der Operand ist der Divisor!) nur Register oder "Variablen" im Speicher (hier reichen 8bit! - sonst musst du den Dividend auch anders verteilen - auf ax:dx oder eax:edx). Konstanten kannst du nicht als Operand angeben.
-
Ich hab nochmal etwas gegoogelt noch was gefunden.
Nur eine Frage dazu hab ich:
sub al,48 ; Hier wird ja was Konvertiert aber von was nach was
int nach string ? string nach int ...
Ich glaub ich kauf mir nachher mal ein Buch von den Tutorial aus dem FAQ fand ich das hier am besten:
http://www.assembler.my100megs.com/ASMPage.pdf
Ich glaub das Buch kauf ich einfach mal.
Kennt das zufälligerweise wer ?
Ansonsten teste ich es einfach mal. ^^
.model small .stack 100h .data zahl1 db 10,13,"Zahl1: ","$" zahl2 db 10,13,"Zahl2: ","$" ausgabe db 10,13,"Ergebniss: ","$" eingabe1 db ? ergebniss db ?,'$' .code entrypoint: mov dx,@data mov ds,dx mov dx,offset zahl1 mov ah,09 int 21h mov ah,01 ; tastatur eingabe die eingabe wird in al gespeichert int 21h sub al,48 ; al konvertieren von int nach string ?? mov eingabe1 ,al ; tasten eingabe in der variable eingabe1 abspeichern mov dx,offset zahl2 mov ah,09 int 21h mov ah,01 int 21h sub al,48 ; die tasten eingabe von zahl2 steht in register al ; die eingabe von zahl2 braucht man nicht noch extra in eine variable schieben ; das macht man nur wenn man mehrere verschiedene zahlen addieren bzw. subtrahieren will add al,eingabe1 ; eingabe1 ist die zahl welche man bei zahl1 eingeben hat al ist für zahl2 add al,48 ; al konvertieren mov ergebniss,al mov dx,offset ausgabe mov ah,09 int 21h mov dx,offset ergebniss mov ah,09 int 21h mov ah,4ch int 21h end entrypoint end
-
Das Buche kenne ich, ist ganz brauchbar für den Einstieg.
Ich rate Dir zu NASM, weil dieser sozusagen freeware standard ist.
-
Ich hab mir das Buch auch erst gekauft. Bin zwar noch net ganz fertig, aber kann es auch empfehlen. Am Anfang wird kurz erklärt was Assembler ist und.. Dann gehts aber auch gleich mit Hallo-World los und dann wird das Programm immer Stück für Stück erklärt.
Wenn du dir es bestellst würde ich aber darauf achten, das du dir gleich die 2. Auflage bestellst.
Ansonsten viel Spaß mit dem Buch
-
Ok ty für die Antworten.
-
add schrieb:
sub al,48 ; Hier wird ja was Konvertiert aber von was nach was
int nach string ? string nach int ...
Weder noch.
In dem Code wird ein Zeichen von der Tastatur eingelesen und zum Schluss auch nur eins ausgegeben. In C waere das wohl ein "char".
Wenn du dir mal eine ASCII-Tabelle ansiehst, sollte dir eigentlich recht schnell aufgehen, was da passiert. ... und dass dieser Code Probleme mit anderen Eingaben als jeweils einer Ziffer, sowie Endergebnissen >9 haben wird.
-
...
push ax
push cx
push dx
mov ah,02
mov dl,bh
mov cl,4
shr dl,cl
add dl,30
cmp dl,39
jle ;(+3)
add dl,07
int 21
mov dl,bh
and dl,0f
add dl,30
cmp dl,39
jle ;(zum int21)
add dl,07
int 21
pop ax
pop cx
pop dx
...