Division in Assembly. Zeichen sind in ASCII gespeichert?
section .text
global main
main:
mov esi, 10 ; ESI holds current number
mov eax, 0 ; EAX holds sum of numbers
push 10 ; Line feed for end of line (Stack is first in, last out -> Line feed will be last char)
mov edi, 10 ; Divisor of 10 for seperating digits of number (used in divisionLoop)
; Sum numbers 1 through 10
sumLoop:
add eax, esi ; Add number to sum
dec esi ; Next number
jnz sumLoop ; Loop until 0
; Seperate eax into its digits, by dividing by 10 multiple times,
; where in each division the remainder will be a single digit
; and the quotient will be the remaining digits used as dividend in next loop run
divisionLoop:
mov edx, 0 ; Make sure edx is empty, as it is used as upper half of dividend
div edi ; Divide eax by edi (= 10) => quotient is in eax (= Rest of digits for next loop), remainder in edx (= Single digit)
add edx, 48 ; Make edx (digit) a char representing its value by adding '0' to it
push edx ; Push char to stack for usage in print later
cmp eax, 0 ; Loop until quotient is 0 (=> no more digits left)
jne divisionLoop
; Print digits from Stack one by one
printLoop:
mov eax, 4
mov ebx, 1
mov ecx, esp ; Print top of stack (esp always points to top of stack)
mov edx, 1 ; Length of 1 byte (= 1 char)
int 80h
pop esi ; Remove top of stack
cmp esi, 10 ; Loop until Line feed is reached
jne printLoop
exit:
mov eax, 1
mov ebx, 0 ; Exit code 0
int 80h
Hallo,
hier steht ein Programm in Assembler, dass die Zahlen von 1 bis 10 addiert.
Die 55 durch 10 teilt und die Reste der Division dann in einem Stack speichert.
push....
Am Ende wird alles über den Standardkanal ausgegeben auf der Konsole.
Wenn ich 55 / 10 teile ergibt das Quotient 5 steht in Register eax und der Rest hier auch 5 in edx Register. Bevor ich jetzt den Rest auf den Stack lege wird die Zahl mit 48 addiert. ergbit 53 ist das char Zeichen 5 im ASCII Code.
Heißt das jetzt, dass die Ergebnisse bei einer ganzzahligen Division im Assembler-Code immer in ASCII-Zeichen gespeichert sind?
1 Antwort
Nein, natürlich heißt es das nicht. ASCII ist nicht anderes als eine Zeichenkodierung, also eine übereinkunft welche "Nummer" ein Zeichen trägt.
Glücklicherweise liegen die Ziffern aufeinanderfolgend beginnen bei 0 in der Kodierung, sodaß die Addition des Wertes von 48 zum Ziffernwert dem Zeichen der Ziffer entspricht.
Das liegt einfach daran, daß der Standardausgabekanal eine Konsole ist und Ziffern in den meisten Kodierungen genauso wie in ASCII kodiert sind.
Würde ich stdout in eien Datei umleiten, dann wäre diese, wenn Du ASCII nach STDOUT schreibst, eben ASCII kodiert, nutzt Du UTF-8, dann UTF-8.
Das Terminal/die Konsole/der Terminalemulator liest quasi Deinen stdout und interpretiert ihn gemäß Festlegung.
"Nein, natürlich heißt es das nicht. ASCII ist nicht anderes als eine Zeichenkodierung, also eine übereinkunft welche "Nummer" ein Zeichen trägt."
=> Ok, Verstanden!
Was ich nicht verstehe ist folgendes im divisions loop:
divisionLoop:
mov edx, 0
div edi
add edx, 48
push edx
...
=> Ich teile wie geschrieben 55 durch 10, wodurch ein Quotient von 5 entsteht, dieser steht im Register eax, und ich habe einen remainder von 5, welcher im Regsiter edx steht.
Jetzt wird hier mit add edx, 48
48 auf den Inhalt des Register edx addiert. Ergbit 53 in ASCII entspricht dem charZeichen 5.
=> D. h. im Register edx steht ursprünglich vor der Addititon +48 der Wert 5
und dieser Wert 5 ist im Assembler Code in ASCII codiert?
Wenn Du vom Quelltext sprichst, dann ja, dort sind Zahlenliterale natürlich ASCII-kodiert, sonst würden sie ja nicht als solche angezeigt.
Im fertigen Binary sieht das natürlich anders aus.
Oder anders gefragt: Du hast mir ma geschrieben, dass wenn ich den Standartkanal zur Ausgabe verwenden will, dann kann muss ich diesem etwas übergeben, mit dem er etwas anfangen kann.
Als ein char oder einen String in Assembly
Woher weiß ich, dass ich den Standardausgabe Kanal in Assembyl eben nur diese Übergeben kann und keine Zahl?