2017-05-21 1 views
0

Dies ist mein Code für jetzt, aber es kann nur 1-stellige Zahlen. Es ist für den Unterricht und ich weiß nicht, wie es mehrere Ziffern machen kann. Ich bin noch ein Anfänger bei ASM Programmierung und ich wollte um Hilfe bitten, wie man mehrere Ziffern macht.Wie Sie mathematische Operationen mit mehreren Ziffern in ASM ausführen

.model small 
.stack 4096h 
.data 
msg1 db 'Choose an operation:$' 
msg2 db 'a. Addition$' 
msg3 db 'b. Subtraction$' 
msg4 db 'c. Multiplication$' 
msg5 db 'd. Division$' 
msg6 db 'You choose Addition.$' 
msg7 db 'You choose Subtraction.$' 
msg8 db 'You choose Multiplication.$' 
msg9 db 'You choose Division.$' 
msg11 db 'First number:$' 
msg12 db 'Second number:$' 
msg13 db 'Operation:$' 
msg14 db 'Answer:$' 
msg15 db 'Enter two numbers then choose the operation.$' 
op1 db ? 
op2 db ? 
res1 db ? 
res2 db ? 

.code 
start: 
mov ax,@data 
mov ds,ax 

_start: 
mov ah, 09h 
lea dx, msg15 
int 21h 
call newline 
mov ah, 09h 
lea dx, msg11 
int 21h 
mov ah, 01h 
int 21h 
sub al,30h 
mov op1, al 
call newline 
mov ah, 09h 
lea dx, msg12 
int 21h 
mov ah, 01h 
int 21h 
sub al,30h 
mov op2, al 
call newline 
mov ah, 09h 
lea dx, msg1 
int 21h 
call newline 
mov ah, 09h 
lea dx, msg2 
int 21h 
call newline 
mov ah, 09h 
lea dx, msg3 
int 21h 
call newline 
mov ah, 09h 
lea dx, msg4 
int 21h 
call newline 
mov ah, 09h 
lea dx, msg5 
int 21h 
call newline 
mov ah, 09h 
lea dx, msg13 
int 21h 
mov ah, 01h 
nt 21h 
cmp al, 'a' 
je _add 
cmp al, 'b' 
je _sub 
cmp al, 'c' 
je _mul 
cmp al, 'd' 
je _div 

_add: 
call newline 
lea dx, msg6 
mov ah, 09h 
int 21h 
call newline 
mov ax, 0 
mov al, op1 
add al, op2 
cmp al,0ah 
jge _twodig 
mov res2,al 
jmp _ans 

_sub: 
call newline 
lea dx, msg7 
mov ah, 09h 
int 21h 
call newline 
mov ax, 0 
mov al, op1 
sub al, op2 
mov res2,al 
mov res1,ah 
jmp _ans 

_mul: 
call newline 
lea dx, msg8 
mov ah, 09h 
int 21h 
call newline 
mov ax,0 
mov bx,0 
mov al, op1 
mov bl, op2 
mul bx 
mov res2,al 
jmp _mans 

_div: 
call newline 
lea dx, msg9 
mov ah, 09h 
int 21h 
call newline 
mov ax,0 
mov bx,0 
Mov dx,0 
mov al, op1 
mov bl, op2 
div bx 
mov res1, dl 
mov res2, al 
jmp _dans 

_twodig: 
sub al, 0ah 
mov ah,01h 
add ax, 3030h 
mov bx, ax 
lea dx, msg14 
mov ah, 09h 
int 21h 
mov dl,bh 
mov ah, 02h 
int 21h 
mov dl,bl 
mov ah, 02h 
int 21h 
jmp _loop 

_ans: 
lea dx, msg14 
mov ah, 09h 
int 21h 
mov al, res2 
add al, 30h 
mov dl,al 
mov ah, 02h 
int 21h 
jmp _loop 

_mans: 
mov dx, 0 
mov bl,0ah 
div bx 
mov ah,dl 
add ax, 3030h 
mov bx,ax 
cmp bl,30h 
je _ans 
lea dx, msg14 
mov ah, 09h 
mov dl,bl 
mov ah, 02h 
int 21h 
mov dl,bh 
mov ah, 02h 
int 21h 
jmp _loop 

_dans: 
lea dx, msg14 
mov ah, 09h 
int 21h 
mov al, res2 
mov ah, res1 
add ax, 3030h 
mov bx, ax 
mov dl,bl 
mov ah, 02h 
int 21h 
mov dl,'r' 
mov ah, 02h 
int 21h 
mov dl,bh 
mov ah, 02h 
int 21h 
jmp _loop 

_loop: 
mov ah,4ch 
int 21h 
newline proc 
mov dl, 0ah 
mov ah, 02h 
int 21h 
mov dl, 0d 
mov ah, 02h 
int 21h 
ret 
newline endp 

end start 
+1

Ich verstehe nicht, warum Sie das so kompliziert gemacht haben. Lesen Sie eine Zahl von der Konsoleneingabe, speichern Sie sie in einem Register, lesen Sie eine andere Zahl von der Konsoleneingabe, speichern Sie sie in einem zweiten Register, und dann "ADD" (oder "SUB" oder "MUL" oder "DIV") diese Register . Abhängig von der Größe der verwendeten Register erhalten Sie Unterstützung für 8-Bit-, 16-Bit-, 32-Bit- oder 64-Bit-Werte. Vielleicht ist das Problem, dass Sie nur 1 Zeichen pro Zeit von der Konsoleneingabe lesen? Erwägen Sie die Verwendung von gepufferten Eingaben oder eine andere Möglichkeit, dass der Benutzer angibt, dass die Eingabe beendet ist. –

+1

@CodyGray Die Änderung des zu verwendenden Codes [gepufferte Eingabe] (http://spike.scu.edu.au/~barry/interrupts.html#ah0a) ist möglicherweise keine große Herausforderung. Aber wenn er sich seinen Code anschaut, scheint er keine echte "atoi" -Funktion zu haben und macht nur "sub al, 30h". Die Schritte zum Drehen der gepufferten Kette "1234" in ein Register können für einen Neuling nicht offensichtlich sein. Horlisch, hilft es, an "1234" als 4 + (3 * 10) + (2 * 100) + (1 * 1000) zu denken? Ja, das wäre ein Schmerz zu schreiben, aber ich glaube nicht, dass Sie irgendwelche Werkzeuge in asm oder dos finden werden, die das für Sie tun werden. Macht Sie wirklich die libs von c schätzen, oder? –

Antwort

0

Es kann helfen, wenn Sie erkennen, wie Computer mit Zahlen arbeiten.

Im Gegensatz zu Menschen können sie abstrakte Entitäten nicht in Gedanken angehen, und das sind Zahlen. Computer brauchen eine physische Repräsentation, um darauf zu reagieren und sie zu verarbeiten.

Aber Menschen tun ähnliches, wenn ich Ihnen etwas über Nummer 1234 erzählen möchte, werde ich es so schreiben "1234", vier Schriftglyphen auf Papier/Bildschirm. Dies ist nicht mehr die reale Zahl, sondern ein Basis-10-formatierter "Spiegel" davon, weit davon entfernt, perfekt zu sein. Und wie liest du es zurück und konvertierst in 1234-Wert? Sie verstehen, dass jede Ziffer eine andere Zehnerpotenz ist, und Sie wissen, wie Sie damit arbeiten.

Für Computer wird das gleiche Prinzip verwendet, aber ihre native Basis ist 2, die Ziffern 0/1 können einfach als Strom/kein Strom in elektrischen Leitungen/Zellen codiert werden, also wird eine einzelne 0/1-Ziffer " Bit". Da ein einzelnes Bit nur zwei Werte speichern kann, neigen wir dazu, sie zusammen 8 zu bilden, um ein Byte zu bilden. Nun kann ein Byte (8 Bits) 2 verschiedene Werte speichern, die bei Interpretation als vorzeichenlose Ganzzahlen den Bereich 0..255 abdecken. 16 Bits können Werte von 0 bis 65535 abdecken (oder anders, wenn Sie die Werte von 16 Bits unterschiedlich interpretieren, zum Beispiel wenn das oberste Bit als Vorzeichenwert interpretiert wird, können Sie ganzzahlige Werte von -32768..+32767 abdecken).

Beachten Sie, dass die 16 Bits keine Informationen haben, welche Art von Wert sie speichern und wie sie interpretiert werden sollen. Sie sind einfach eine Gruppe von sechzehn 0/1-Werten, und wie Sie sie interpretieren (vorzeichenlos, signiert, separate Bit-Flags oder sogar Float mit niedriger Genauigkeit oder nur Farbe auf dem Bildschirm oder Frequenz des Klangs, ...), es ist bis zu [ Ihr] Code, um diesen Wert in irgendeiner Weise zu interpretieren.

8086-Register sind 16 Bit. Wenn Sie native arithmetische Anweisungen wie ADD, SUB, MUL, DIV verwenden möchten, müssen Sie Ihre Werte zuerst in 8/16 Bit codieren.

Bei Eingabe vom Benutzer haben Sie normalerweise separate ASCII-Zeichen.

So, wenn Benutzer "Nummer" 1234 eingeben, erhalten Sie oft zum Beispiel 5 Bytes von Werten: 49, 50, 51, 52, 13 (die letzte 13 ist "Enter" -Taste). Versuchen Sie nun, den folgenden Algorithmus in den Kopf zu führen:

Nach der ersten Schleife bx wird 1 sein (49-48 + 0).
Nach der zweiten Schleife bx wird 12 (50-48 + 1 * 10).
Nach der dritten Schleife Bx wird 123 (51-48 + 12 * 10).
Nach der vierten Schleife bx wird 1234 (52-48 + 123 * 10).
Dann erkennt die while-Bedingung die Eingabe und überspringt die Berechnung, und in bx haben Sie den Wert 1234 binär codiert in 16 Bits (d. H. Die Elektrizität ist in Zellen: 0000 0100 1101 0010).

Das ist also eine der Möglichkeiten, wie man aus einzelnen Ziffern Zeichen in native Binärwert umwandeln kann.

Um das Ergebnis anzuzeigen, müssen Sie die umgekehrte Transformation durchführen, indem Sie den nativen Binärwert in Ziffern für eine bestimmte Zehnerpotenz aufteilen, diese in ASCII-Zeichen umwandeln und sie in Bildschirm/Datei/etc ausgeben.

All dies ist in der Regel leicht in jeder höheren Programmiersprache, aber selten in ASM (einige Anfänger freundliche Plattformen bieten dies als Teil der OS-Anrufe, aber DOS ist nicht einer von ihnen).

Das heißt, um Ihre eigenen vollständigen + richtigen Ersatz für CLIB printf und scanf ist Projekt für ein paar Wochen, und ich spreche nicht einmal über Effizienz. Aber solange Sie nur einige einfache Integer-Conversions zum Lernen und Spielen benötigen, ist es an einem oder mehreren Tagen möglich. Erkenne einfach, was ist was, und achte darauf, wie verschiedene Arten von Werten im Computer in die Bits (und wie viele davon) kodiert sind. Dann können einfache mathematische Formeln verwendet werden, um von einer Darstellung in eine andere zu konvertieren.


BTW, gibt es Möglichkeiten (Formeln), wie alle um die Arithmetik zu tun, auch mit separaten Ziffern (das heißt Berechnung zu tun mit „Strings“). Dies ist manchmal sogar praktisch, einige Bibliotheken mit "beliebiger Genauigkeit" verwenden ein ähnliches Prinzip, um mit Werten zu rechnen, die nicht in native 8/16/32/64/128 Bitwerte passen. Die obige Antwort sollte eher wie "Unlocker" sein, um Ihnen eine Idee zu geben, was Sie in Händen haben und dass Sie jede gewünschte Konvertierung/Berechnung durchführen können, wenn Sie verstehen, was was ist und wie es in der CPU funktioniert. Es ist nicht der einzige Weg, wie man mit Werten arbeitet.

Verwandte Themen