
Atmel Integer
5.2.1 Integer Arithmetik (8-Bit, 16-Bit, 32-Bit und 64-Bit) (in Arbeit)
Die Schreibweise erfolgt im binären, im dezimalen und im hexadezimalen
System.
Binäre Zahlen werden durch ein % Zeichen gekennzeichnet.
Hexadezimale Zahlen werden durch ein $ Zeichen gekennzeichnet.
Dezimale Zahlen besitzen keine Kennung.
165 = $A5 = %10100101
Wird der Definitionsbereich einer Zahl über- oder
unterschritten ist das Carry-Flag gesetzt.
Bit 0 aus einem Byte wird auch als LSB (Least Significant Bit) bezeichnet.
Das Bit mit der kleinsten Wertigkeit. Bit 7 aus einem Byte wird auch als
MSB (Most Significant Bit) bezeichnet. Das Bit mit der größten
Wertigkeit. Die Zählweise ist von rechts nach links und von 0 bis 7.
Daraus läßt sich gleich die Wertigkeit der einzelnen Bits berechnen:
Bit |
Exponent |
Wertigkeit |
0 |
20 |
1 |
1 |
21 |
2 |
2 |
22 |
4 |
3 |
23 |
8 |
4 |
24 |
16 |
5 |
25 |
32 |
6 |
26 |
64 |
7 |
27 |
128 |
Download der 8-Bit Funktionen
Der Wertebereich besteht nur aus positiven Zahlen von 0 bis 255.
| Hex |
Dez |
| $00 |
0 |
| ... |
... |
| $7F |
127 |
| $80 |
128 |
| ... |
... |
| $FF |
255 |
-
;****************************************************************
-
; Byte (8 Bit) in HEX-String umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; r16 = Byte
-
; Output: X = Zeigt auf Stringende
-
; r16 = 0
-
; Return: -
-
; Modify: -
-
;
-
H1ToStr: push r16
-
swap r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
rcall NibToChr
-
st X+,r16
-
ldi r16,0x00
-
st X,r16
-
ret
|
-
;****************************************************************
-
; Byte (8 Bit) in DEZ-String umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; r16 = Byte
-
; Output: X = Zeigt auf Stringende
-
; r16 = 0
-
; Return: -
-
; Modify: -
-
;
-
B1ToStr: push r17
-
mov r17,r16
-
-
clr r16
;100er Zähler löschen
-
B1ToStr1: cpi r17,100 ;ist Byte < 100 ?
-
brcs B1ToStr2
;ja
-
sbci r17,100
;nein
-
inc r16
;100er Zähler inkrementieren
-
rjmp B1ToStr1
;Wiederholen bis Byte < 100 ist
-
B1ToStr2: rcall NibToChr ;100er in ASCII umwandeln
-
st X+,r16
;100er in den String schreiben
-
-
clr r16
;10er Zähler löschen
-
B1ToStr3: cpi r17,10 ;ist Byte < 10 ?
-
brcs B1ToStr4
;ja
-
sbci r17,10
;nein
-
inc r16
;10er Zähler inkrementieren
-
rjmp B1ToStr3
;Widerholen bis Byte < 10 ist
-
B1ToStr4: rcall NibToChr ;10er in ASCII umwandeln
-
st X+,r16
;10er in den String schreiben
-
-
mov r16,r17
;1er bleiben übrig
-
rcall NibToChr ;1er
in ASCII umwandeln
-
st X+,r16
;1er in den String schreiben
-
clr r16
-
st X,r16
;String mit 0 abschliessen
-
pop r17
-
ret
|
Der String enthält führende Nullen, $20 wird zu '032'.
-
;****************************************************************
-
; 1 Byte (8 Bit) von HEX-String in Byte umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; Output: X = Zeigt auf Stringende
-
; r16 = Byte
-
; Return: -
-
; Modify: -
-
;
-
StrToH1: push r17
-
ld r16,X+
-
rcall ChrToNib
-
swap r16
-
mov r17,r16
-
ld r16,X+
-
rcall ChrToNib
-
or r16,r17
-
pop r17
-
ret
|
-
;****************************************************************
-
; 8 nach 16 Bit Konvertierung
-
; Input: r16 = Byte
-
; Output: r16 = r16
-
; r17 = 0
-
; Return: -
-
; Modify: -
-
;
-
B1ToB2: clr r17
-
ret
|
Standard Befehl des ATmega
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 0,25 µs
-
Takte: 1
-
;****************************************************************
-
; Addition zweier Zahlen
-
; Input: r16 = Byte
-
; r17 = Byte
-
; Output: r16 = r16 + r17
-
; Return: C = 0 = kein Überlauf
-
; C = 1 = Das Ergebnis ist > 255
-
; Modify: -
-
;
-
uadd1: add r16,r17
-
ret
|
Standard Befehl des ATmega
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 0,25 µs
-
Takte: 1
-
;****************************************************************
-
; Subtraction zweier Zahlen
-
; Input: r16 = Byte
-
; r17 = Byte
-
; Output: r16 = r16 - r17
-
; Return: C = 0 = kein Ünterlauf
-
; C = 1 = Das Ergebnis ist < 0
-
; Modify: -
-
;
-
usub1: sub r16,r17
-
ret
|
Standard Befehl des ATmega
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 3,00 µs
-
Takte: 12
-
;****************************************************************
-
; Multiplikation zweier Zahlen
-
; Input: r16 = Multiplikant
-
; r17 = Multiplikator
-
; Output: r16 = Product Low
-
; r17 = Product High
-
; Return: C = 0 = Das Ergebnis ist 1 Byte
-
; C = 1 = Das Ergebnis ist > 1
Byte
-
; Modify: -
-
;
-
umul1: push r0
-
push r1
-
mul r16,r17
-
mov r16,r0
-
mov r17,r1
-
clc
-
tst r17
-
breq umul1a
-
sec
-
umul1a: pop r1
-
pop r0
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 26 µs
-
Takte: 104
-
;****************************************************************
-
; Vorzeichenlose Division 8Bit / 8Bit
-
; Input: r16 = Divident
-
; r17 = Divisor
-
; Output: r16 = Ergebnis
-
; r17 = Rest
-
; Return: c = 0 = Alles klar
-
; c = 1 = Divident < Divisor
-
; Modify: -
-
;
-
; Wenn Fehler dann keine Änderung von Divident und Divisor
-
;
-
udiv1: cp r16,r17 ;Divident muß
> Divisor sein
-
brcs udiv1d
-
tst r17
;Divisor darf nicht 0 sein
-
breq udiv1d
-
push r18
-
push r19
-
sub r18,r18 ;clear
remainder and carry
-
ldi r19,9
;init loop counter
-
udiv1a: rol r16 ;shift left
dividend
-
dec r19
;decrement counter
-
breq udiv1c ;if
done
-
rol r18
;shift dividend into remainder
-
sub r18,r17
;remainder = remainder - divisor
-
brcc udiv1b ;if
result negative
-
add r18,r17 ;
restore remainder
-
clc
; clear c to be shifted into result
-
rjmp udiv1a
;else
-
udiv1b: sec ;
set carry to be shifted into result
-
rjmp udiv1a
-
udiv1c: mov r17,r18
-
pop r19
-
pop r18
-
clc
-
udiv1d: ret
|
Der Wertebereich besteht aus negativen und positiven Zahlen von -128 bis
127.
| Hex |
Dez |
| $00 |
0 |
| ... |
... |
| $7F |
127 |
| $80 |
-128 |
| ... |
... |
| $FF |
-1 |
-
;****************************************************************
-
; Byte (8 Bit) in DEZ-String umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; r16 = Byte
-
; Output: X = Zeigt auf Stringende
-
; r16 = 0
-
; Return: -
-
; Modify: -
-
;
-
B1SToStr: tst r16 ;Byte testen
-
brpl B1SToS1 ;ist
positiv, also Ausgabe
-
neg r16
;in positive Zahl wandeln
-
brvc B1SToS2 ;Byte
ist < 128
-
ldi r16,128
;Byte war -128
-
B1SToS2: push r16
-
ldi r16,'-'
;Vorzeichen ausgeben
-
st X+,r16
-
pop r16
-
B1SToS1: rcall B1SToStr ;Byte in ASCII umwandeln
-
ret
|
Der String enthält führende Nullen, $20 wird zu '032'. Das Vorzeichen
wird nur ausgegeben, wenn es negativ ist.
-
;****************************************************************
-
; 1 Byte (8 Bit) von HEX-String in Byte umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; Output: X = Zeigt auf Stringende
-
; r16 = Byte
-
; Return: c = 0 = Alles klar
-
; c = 1 = Byte ist < -128 oder
> 127
-
; Modify: -
-
;
-
StrToSH1: push r17
-
clr r17
;Vorzeichen ist positiv
-
ld r16,X
-
cpi r16,'-'
-
brne StrToSH1a ;ist
tatsächlich positiv
-
neg r17
;negatives Vorzeichen merken
-
adiw XH:XL,1
;Vorzeichen aus String entfernen
-
StrToSH1a: rcall StrToH1 ;String in Byte umwandeln
-
clc
-
tst r17
;Vorzeichen testen
-
breq StrToSH1b ;Zahl
war positiv
-
cpi r16,129
;Gültige Zahl?
-
brlo StrToSH1c ;alles
klar
-
sec
;Byte ist < -128
-
rjmp StrToSH1c
-
StrToSH1b: cpi r16,128 ;Gültige Zahl?
-
brlo StrToSH1c ;alles
klar
-
sec
;Byte ist > 127
-
StrToSH1c: pop r17
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 1 µs
-
Takte: 4
-
;****************************************************************
-
; 8 nach 16 Bit Konvertierung
-
; Input: r16 = Byte
-
; Output: r16 = r16
-
; r17 = $00 wenn positiv, $FF wenn negativ
-
; Return: -
-
; Modify: -
-
;
-
B1ToB2: clr r17
-
tst r16
-
brpl B1ToB2a
-
subi r17,1
-
B1ToB2a: ret
|
Standard Befehl des ATmega
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 1,50 µs
-
Takte: 6
-
;****************************************************************
-
; Addition zweier Zahlen
-
; Input: r16 = Byte
-
; r17 = Byte
-
; Output: r16 = r16 + r17
-
; Return: C = 0 = alle klar
-
; C = 1 = Das Ergebnis ist > 127
oder < -128
-
; Modify: -
-
;
-
sadd1: add r16,r17
-
clc
-
brvs sadd1a
-
sec
-
sadd1a: ret
|
Standard Befehl des ATmega
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 1,50 µs
-
Takte: 6
-
;****************************************************************
-
; Subtraction zweier Zahlen
-
; Input: r16 = Byte
-
; r17 = Byte
-
; Output: r16 = r16 - r17
-
; Return: C = 0 = alles klar
-
; C = 1 = Das Ergebnis ist <
-128
-
; Modify: -
-
;
-
ssub1: sub r16,r17
-
clc
-
brvs ssub1a
-
sec
-
ssub1a: ret
|
Standard Befehl des ATmega
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 5,00 µs
-
Takte: 20
-
;****************************************************************
-
; Multiplikation zweier Zahlen
-
; Input: r16 = Multiplikant
-
; r17 = Multiplikator
-
; Output: r16 = Product Low
-
; r17 = Product High
-
; Return: C = 0 = Das Ergebnis ist 1 Byte
-
; C = 1 = Das Ergebnis ist 2 Byte
-
; Modify: -
-
;
-
smul1: push r0
-
push r1
-
muls r16,r17
-
mov r16,r0
-
mov r17,r1
-
clc
-
tst r17
-
breq smul1a
-
cpi r17,$FF
-
breq smul1a
-
sec
-
smul1a: pop r1
-
pop r0
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 33 µs
-
Takte: 132
-
;****************************************************************
-
; Vorzeichbehaftete Division 8Bit / 8Bit
-
; Input: r16 = Divident
-
; r17 = Divisor
-
; Output: r16 = Ergebnis
-
; r17 = Rest
-
; Return: c = 0 = Alles klar
-
; c = 1 = Abs(Divident) <
Abs(Divisor)
-
; Modify: -
-
;
-
; Wenn Fehler dann keine Änderung von Divident und Divisor
-
;
-
sdiv1: push r18
-
clr r18
-
tst r16
;wenn Divident negativ
-
brpl sdiv1a
-
sbr r18,1
;dann Vorzeichen merken
-
neg r16
;und positiv machen
-
sdiv1a: tst r17 ;wenn
Divisor negativ
-
brpl sdiv1b
-
sbr r18,2
;dann Vorzeichen merken
-
neg r17
;und positiv machen
-
sdiv1b: rcall udiv1 ;Vorzeichenlose
Division
-
cpi r18,0
;waren beide Vorzeichen positiv ?
-
breq sdiv1c
;ja
-
cpi r18,3
;waren beide Vorzeichen negativ ?
-
breq sdiv1c
;ja
-
neg r16
;Ergebnis wird negativ, wenn
-
neg r17
;ein Vorzeichen negativ war
-
sdiv1c: pop r18
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 3,25 µs
-
Takte: 13
-
;****************************************************************
-
; Absolutbildung
-
; Input: r16 = Byte
-
; Output: r16 = Abs(r16)
-
; Return: C = 0 = alle klar
-
; C = 1 = Das Ergebnis ist > 127
-
; Modify: -
-
;
-
sabs1: clc
-
tst r16
-
brpl sabs1a
-
neg r16
-
brvc sabs1a
-
sec
-
sabs1a: ret
|
Word |
| 7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
Byte 0 |
Byte 1 |
| 7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Bit 0 aus einem Byte wird auch als LSB (Least Significant Bit) bezeichnet.
Das Bit mit der kleinsten Wertigkeit. Bit 15 aus einem Word wird auch als
MSB (Most Significant Bit) bezeichnet. Das Bit mit der größten
Wertigkeit. Die Zählweise der Bytes ist von links nach rechts und von
0 bis 15. Daraus läßt sich gleich die Wertigkeit der einzelnen
Bits berechnen:
Bit |
Exponent |
Wertigkeit |
0 |
20 |
1 |
1 |
21 |
2 |
2 |
22 |
4 |
3 |
23 |
8 |
4 |
24 |
16 |
5 |
25 |
32 |
6 |
26 |
64 |
7 |
27 |
128 |
8 |
28 |
256 |
9 |
29 |
512 |
10 |
210 |
1024 |
11 |
211 |
2048 |
12 |
212 |
4096 |
13 |
213 |
8192 |
14 |
214 |
16384 |
15 |
215 |
32768 |
Der Wertebereich besteht nur aus positiven Zahlen von 0 bis 65535.
| Hex |
Dez |
| $0000 |
0 |
| ... |
... |
| $7FFF |
32767 |
| $8000 |
32768 |
| ... |
... |
| $FFFF |
65535 |
-
;****************************************************************
-
; 2 Bytes (16 Bit) in HEX-String umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; r16 = Low Byte
-
; r17 = High Byte
-
; Output: X = Zeigt auf Stringende
-
; r16 = 0
-
; r17 = 0
-
; Return: -
-
; Modify: -
-
;
-
H2ToStr: push r16
-
push r17
-
mov r16,r17
-
swap r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
push r16
-
swap r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
rcall NibToChr
-
st X+,r16
-
clr r16
-
clr r17
-
st X,r16
-
ret
|
-
;****************************************************************
-
; 2 Bytes (16 Bit) in DEZ-String umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; r16 = Low Byte
-
; r17 = High Byte
-
; Output: X = Zeigt auf Stringende
-
; r16 = 0
-
; r17 = 0
-
; Return: -
-
; Modify: -
-
;
-
B2ToStrX: cp r18,r20
-
cpc r17,r19
-
brcs B2ToStrY
-
sbc r18,r20
-
sbc r17,r19
-
inc r16
-
rjmp B2ToStrX
-
B2ToStrY: rcall NibToChr
-
ret
-
-
B2ToStr: push r18
-
push r19
-
push r20
-
mov r18,r16
-
clr r16
;10000er Zähler löschen
-
ldi r19,high(10000)
-
ldi r20,low(10000)
-
rcall B2ToStrX
-
st X+,r16
;10000er in den String schreiben
-
clr r16
;1000er Zähler löschen
-
ldi r19,high(1000)
-
ldi r20,low(1000)
-
rcall B2ToStrX
-
st X+,r16
;1000er in den String schreiben
-
clr r16
;100er Zähler löschen
-
ldi
r19,high(100)
-
ldi r20,low(100)
-
rcall B2ToStrX
-
st X+,r16
;100er in den String schreiben
-
clr r16
;10er Zähler löschen
-
ldi r19,high(10)
-
ldi r20,low(10)
-
rcall B2ToStrX
-
st X+,r16
;10er in den String schreiben
-
mov r16,r18
;1er bleiben übrig
-
rcall NibToChr
;1er in ASCII umwandeln
-
st X+,r16
;1er in den String schreiben
-
clr r16
-
clr r17
-
st X,r16
;String mit 0 abschliessen
-
pop r20
-
pop r19
-
pop r18
-
ret
|
-
;****************************************************************
-
; 16 nach 32 Bit Konvertierung
-
; Input: r16 = Low Byte
-
; r17 = High Byte
-
; Output: r16 = r16
-
; r17 = r17
-
; r18 = 0
-
; r19 = 0
-
; Return: -
-
; Modify: -
-
;
-
B2ToB4: clr r18
-
clr r19
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 2,25 µs
-
Takte: 9
-
;****************************************************************
-
; Addition zweier Zahlen
-
; Input: r16,r17 = Low,High Byte 1
-
; r18,r18 = Low,High Byte 2
-
; Output: r16,r17 = r16,r17 + r18,r19
-
; Return: C = 0 = kein Überlauf
-
; C = 1 = Das Ergebnis
ist > 255
-
; Modify: -
-
;
-
uadd2: add r16,r18
-
adc r17,r19
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 2,25µs
-
Takte: 9
-
;****************************************************************
-
; Addition zweier Zahlen
-
; Input: r16,r17 = Low,High Byte 1
-
; r18,r18 = Low,High Byte 2
-
; Output: r16,r17 = r16,r17 - r18,r19
-
; Return: C = 0 = kein Unterlauf
-
; C = 1 = Das Ergebnis
ist < 0
-
; Modify: -
-
;
-
usub2: sub r16,r18
-
sbc r17,r19
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 14,00 µs
-
Takte: 56
-
;****************************************************************
-
; Multiplikation zweier Zahlen
-
; Input: r16,r17 = Low,High Multiplikant
-
; r18,r19 = Low,High Multiplikator
-
; Output: r16,r17 = Low,High Product Low
-
; r18,r19 = Low,High Product High
-
; Return: C = 0 = Das Ergebnis ist 2 Byte
-
; C = 1 = Das Ergebnis
ist > 2 Byte
-
; Modify: -
-
;
r5 r4 r3 r2
-
; Beispiel: r17 r16 * r19 r18 = r19 r18 r17 r16
-
; 12 34 * 56 78
= 06 26 00 60
-
;
----------------------------------
-
; 12 * 56
= 06 0C
-
; 12 *
78 = 08 70
-
; 34 * 56
= 11 78
-
; 34 *
78 = 18 60
-
;
--------------
-
;
06 26 00 60
-
umul2: push r0
-
push r1
-
push r2
-
push r3
-
push r4
-
push r5
-
mul r17,r19
-
mov r4,r0
-
mov r5,r1
-
mul r16,r18
-
mov r2,r0
-
mov r3,r1
-
mul r16,r19
-
add r3,r0
-
adc r4,r1
-
mul r17,r18
-
add r3,r0
-
adc r4,r1
-
mov r16,r2
-
mov r17,r3
-
mov r18,r4
-
mov r19,r5
-
clc
-
tst r19
-
brne umul2b
;Fehler
-
tst r18
-
breq umul2a
;kein Fehler
-
umul2b: sec
-
umul2a: pop r5
-
pop r4
-
pop r3
-
pop r2
-
pop r1
-
pop r0
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 64,75 µs
-
Takte: 259
-
;****************************************************************
-
; Vorzeichenlose Division 16Bit / 16Bit
-
; Input: r16 = Divident Low Byte
-
; r17 = Divident High Byte
-
; r18 = Divisor Low Byte
-
; r19 = Divisor High Byte
-
; Output: r16 = Ergebnis Low Byte
-
; r17 = Ergebnis High Byte
-
; r18 = Rest Low Byte
-
; r19 = Rest High Byte
-
; Return: c = 0 = Alles klar
-
; c = 1 = Fehler (Divident < Divisor)
oder (Divisor = 0)
-
; Modify: -
-
;
-
; Wenn Fehler dann keine Änderung von Divident und Divisor
-
;
-
udiv2: cp r17,r19 ;Divident muß
> als Divisor sein
-
brcs udiv2f
-
brne udiv2a
-
cp r16,r18
-
brcs udiv2f
-
udiv2a: tst r18 ;Divisor
darf nicht 0 sein
-
brne udiv2b
-
tst r19
-
brne udiv2b
-
sec
-
brcs udiv2f
-
udiv2b: push r20
-
push r21
-
push r22
-
clr r21
;clear remainder Low byte
-
sub r22,r22 ;clear
remainder High byte and carry
-
ldi r20,17
;init loop counter
-
udiv2c: rol r16 ;shift left
dividend
-
rol r17
-
dec r20
;decrement counter
-
breq udiv2e ;if
done
-
rol r21
;shift dividend into remainder
-
rol r22
-
sub r21,r18
;remainder = remainder - divisor
-
sbc r22,r19 ;
-
brcc udiv2d
;if result negative
-
add r21,r18 ;
restore remainder
-
adc r22,r19
-
clc
; clear c to be shifted into result
-
rjmp udiv2c
;else
-
udiv2d: sec
; set c to be shifted into result
-
rjmp udiv2c
-
udiv2e: mov r18,r21 ;Ergebnis umschichten
-
mov r19,r22
-
pop r22
-
pop r21
-
pop r20
-
udiv2f: ret
|
Der Wertebereich besteht nur aus Zahlen von -32768 bis 32767.
| Hex |
Dez |
| $0000 |
0 |
| ... |
... |
| $7FFF |
32767 |
| $8000 |
-32768 |
| ... |
... |
| $FFFF |
-1 |
Doubleword |
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
| 7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Bit 0 aus einem Byte wird auch als LSB (Least Significant Bit) bezeichnet.
Das Bit mit der kleinsten Wertigkeit. Bit 31 aus einem Word wird auch als
MSB (Most Significant Bit) bezeichnet. Das Bit mit der größten
Wertigkeit. Die Zählweise ist von links nach rechts und von 0 bis 31.
Daraus läßt sich gleich die Wertigkeit der einzelnen Bits berechnen:
Bit |
Exponent |
Wertigkeit |
|
Bit |
Exponent |
Wertigkeit |
0 |
20 |
1 |
|
16 |
216 |
65536 |
1 |
21 |
2 |
|
17 |
217 |
131072 |
2 |
22 |
4 |
|
18 |
218 |
262144 |
3 |
23 |
8 |
|
19 |
219 |
524288 |
4 |
24 |
16 |
|
20 |
220 |
1048576 |
5 |
25 |
32 |
|
21 |
221 |
2097152 |
6 |
26 |
64 |
|
22 |
222 |
4194304 |
7 |
27 |
128 |
|
23 |
223 |
8388608 |
8 |
28 |
256 |
|
24 |
224 |
16777216 |
9 |
29 |
512 |
|
25 |
225 |
33554432 |
10 |
210 |
1024 |
|
26 |
226 |
67108864 |
11 |
211 |
2048 |
|
27 |
227 |
134217728 |
12 |
212 |
4096 |
|
28 |
228 |
268435456 |
13 |
213 |
8192 |
|
29 |
229 |
536870912 |
14 |
214 |
16384 |
|
30 |
230 |
1073741824 |
15 |
215 |
32768 |
|
31 |
231 |
2147483648 |
Der Wertebereich besteht nur aus positiven Zahlen von 0 bis 4294967295.
| Hex |
Dez |
| $00000000 |
0 |
| ... |
... |
| $7FFFFFFF |
2147483647 |
| $80000000 |
2147483648 |
| ... |
... |
| $FFFFFFFF |
4294967295 |
-
;****************************************************************
-
; 4 Bytes (32 Bit) in HEX-String umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; r16 = Low Byte
-
; r17 =
-
; r18 =
-
; r19 = High Byte
-
; Output: X = Zeigt auf Stringende
-
; r16 = 0
-
; r17 = 0
-
; r18 = 0
-
; r19 = 0
-
; Return: -
-
; Modify: -
-
;
-
H4ToStr: push r16
-
-
push r19
-
mov r16,r19
-
swap r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
rcall NibToChr
-
st X+,r16
-
-
push r18
-
mov r16,r18
-
swap r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
rcall NibToChr
-
st X+,r16
-
-
push r17
-
mov r16,r17
-
swap r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
rcall NibToChr
-
st X+,r16
-
-
pop r16
-
push r16
-
swap r16
-
rcall NibToChr
-
st X+,r16
-
pop r16
-
rcall NibToChr
-
st X+,r16
-
-
clr r16
-
clr r17
-
clr r18
-
clr r19
-
st X,r16
-
ret
|
-
;****************************************************************
-
; 4 Bytes (32 Bit) in DEZ-String umwandeln
-
; Input: X = Pointer auf Stringanfang im SRAM
-
; r16 = Low Byte
-
; r17
-
; r18
-
; r19 = High Byte
-
; Output: X = Zeigt auf Stringende
-
; r16 = 0
-
; r17 = 0
-
; r18 = 0
-
; r19 = 0
-
; Return: -
-
; Modify: -
-
;
-
B4ToStrX: cp r16,r20
-
cpc r17,r21
-
cpc r18,r22
-
cpc r19,r23
-
brcs B4ToStrY
-
sbc r16,r20
-
sbc r17,r21
-
sbc r18,r22
-
sbc r19,r23
-
inc r24
-
rjmp B4ToStrX
-
B4ToStrY: push r16
-
mov r16,r24
-
rcall NibToChr
-
mov r24,r16
-
pop r16
-
ret
-
-
B4ToStr: push r20
-
push r21
-
push r22
-
push r23
-
push r24
-
clr r24
;Zähler löschen
-
ldi r20,0x00
;Lade 1.000.000.000
-
ldi r21,0xCA
-
ldi r22,0x9A
-
ldi r23,0x3B
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0x00
;Lade 100.000.000
-
ldi r21,0xE1
-
ldi r22,0xF5
-
ldi r23,0x05
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0x80
;Lade 10.000.000
-
ldi r21,0x96
-
ldi r22,0x98
-
ldi r23,0x00
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0x40
;Lade 1.000.000
-
ldi r21,0x42
-
ldi r22,0x0F
-
ldi r23,0x00
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0xA0
;Lade 100.000
-
ldi r21,0x86
-
ldi r22,0x01
-
ldi r23,0x00
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0x10
;Lade 10.000
-
ldi r21,0x27
-
ldi r22,0x00
-
ldi r23,0x00
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0xE8
;Lade 1.000
-
ldi r21,0x03
-
ldi r22,0x00
-
ldi r23,0x00
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0x64
;Lade 100
-
ldi r21,0x00
-
ldi r22,0x00
-
ldi r23,0x00
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
clr r24
;Zähler löschen
-
ldi r20,0x0A
;Lade 10
-
ldi r21,0x00
-
ldi r22,0x00
-
ldi r23,0x00
-
rcall B4ToStrX
-
st X+,r24
;Zähler in String schreiben
-
rcall NibToChr ;1er
in ASCII umwandeln
-
st X+,r16
;1er in den String schreiben
-
clr r16
-
clr r17
-
clr r18
-
clr r19
-
st X,r16
;String mit 0 abschliessen
-
pop r24
-
pop r23
-
pop r22
-
pop r21
-
pop r20
-
ret
|
-
;****************************************************************
-
; 16 nach 32 Bit Konvertierung
-
; Input: r16 = Low Byte
-
; r17 = Byte
-
; r18 = Byte
-
; r19 = High Byte
-
; Output: r16 = r16
-
; r17 = r17
-
; r18 = r18
-
; r19 = r19
-
; r20 = 0
-
; r21 = 0
-
; r22 = 0
-
; r23 = 0
-
; Return: -
-
; Modify: -
-
;
-
B4ToB8: clr r20
-
clr r21
-
clr r22
-
clr r23
-
ret
|
-
;****************************************************************
-
; Multiplikation zweier Zahlen
-
; Input: r16,r17,r18,r19 = Low .. High Multiplikant
-
; r20,r21,r22,r23 = Low .. High
Multiplikator
-
; Output: r16,r17,r18,r19 = Low .. High Product Low
-
; r20,r21,r22,r23 = Low .. High Product
High
-
; Return: C = 0 = Das Ergebnis ist 4 Byte
-
; C = 1 = Das Ergebnis
ist > 4 Byte
-
; Modify: -
-
;
r7 r6 r5
r4 r3 r2 r1 r0
-
; Beispiel: r19r18r17r16*r23r22r21r20 = r23r22r21r20r19r18r17r16
-
; 10 20 30 40 * 50 60 70 80 =
-
;
----------------------------------------------------
-
; 10
* 50 = 05 00
-
; 10
* 60 = 06 00
-
; 10
* 70 =
07 00
-
; 10
* 80 =
08 00
-
; 20
* 50 = 0A 00
-
; 20
* 60 =
0C 00
-
; 20
* 70 =
0E 00
-
; 20
* 80 =
10 00
-
; 30
* 50 = 0F 00
-
; 30
* 60 =
12 00
-
; 30
* 70 =
15 00
-
; 30 *
80 =
18 00
-
;
40 * 50 = 14
00
-
;
40 * 60 =
18 00
-
;
40 * 70 =
1C 00
-
;
40 * 80 =
20 00
-
;
-----------------------
-
;
05 10 22 3C
3D 34 20 00
-
;
-
umul4: push r0
-
push r1
-
push r2
-
push r3
-
push r4
-
push r5
-
pop r5
-
pop r4
-
pop r3
-
pop r2
-
pop r1
-
pop r0
-
ret
|
Daten für Atmega8:
-
CPU Takt: 4 MHz
-
Laufzeit: 192 µs
-
Takte: 760
-
;****************************************************************
-
; Vorzeichenlose Division 32Bit / 32Bit
-
; Input: r16 = Divident Low Byte
-
; r17 = Divident
-
; r18 = Divident
-
; r19 = Divident High Byte
-
; r20 = Divisor Low Byte
-
; r21 = Divisor
-
; r22 = Divisor
-
; r23 = Divisor High Byte
-
; Output: r16 = Ergebnis Low Byte
-
; r17 = Ergebnis
-
; r18 = Ergebnis
-
; r19 = Ergebnis High Byte
-
; r20 = Rest Low Byte
-
; r21 = Rest
-
; r22 = Rest
-
; r23 = Rest High Byte
-
; Return: c = 0 = Alles klar
-
; c = 1 = Fehler (Divident < Divisor)
or (Divisor = 0)
-
; Modify: -
-
;
-
; Wenn Fehler dann keine Änderung von Divident oder Divisor
-
;
-
udiv32: cp r19,r23 ;Divident muß
> als Divisor sein
-
brcs udiv32f
-
brne udiv32a
-
cp r18,r22
-
brcs udiv32f
-
brne udiv32a
-
cp r17,r21
-
brcs udiv32f
-
brne udiv32a
-
cp r16,r20
-
brcs udiv32f
-
udiv32a: tst r20 ;Divisor
darf nicht 0 sein
-
brne udiv32b
-
tst r21
-
brne udiv32b
-
tst r22
-
brne udiv32b
-
tst r23
-
brne udiv32b
-
sec
-
brcs udiv32f
-
udiv32b: push r24
-
push r25
-
push r26
-
push r27
-
push r28
-
clr r25
;clear remainder Low byte
-
clr r26
-
clr r27
-
sub r28,r28
;clear remainder High byte and carry
-
ldi r24,33
;init loop counter
-
udiv32c: rol r16 ;shift
left dividend
-
rol r17
-
rol r18
-
rol r19
-
dec r24
;decrement counter
-
breq udiv32e
;if done
-
rol r25
;shift dividend into remainder
-
rol r26
-
rol r27
-
rol r28
-
sub r25,r20
;remainder = remainder - divisor
-
sbc r26,r21
;
-
sbc r27,r22
-
sbc r28,r23
-
brcc udiv32d
;if result negative
-
add r25,r20 ;
restore remainder
-
adc r26,r21
-
adc r27,r22
-
adc r28,r23
-
clc
; clear c to be shifted into result
-
rjmp udiv32c
;else
-
udiv32d: sec ;
set c to be shifted into result
-
rjmp udiv32c
-
udiv32e: mov r20,r25 ;Ergebnis
umschichten
-
mov r21,r26
-
mov r22,r27
-
mov r23,r28
-
pop r28
-
pop r27
-
pop r26
-
pop r25
-
pop r24
-
udiv32f: ret
|
Der Wertebereich besteht nur aus positiven Zahlen von -2147483648 bis 2147483647.
| Hex |
Dez |
| $00000000 |
0 |
| ... |
... |
| $7FFFFFFF |
2147483647 |
| $80000000 |
-2147483648 |
| ... |
... |
| $FFFFFFFF |
-1 |
|
| Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
Byte 4 |
Byte 5 |
Byte 6 |
Byte 7 |
| 7 |
... |
0 |
7 |
... |
0 |
7 |
... |
0 |
7 |
... |
0 |
7 |
... |
0 |
7 |
... |
0 |
7 |
... |
0 |
7 |
... |
0 |
Bit 0 aus einem Byte wird auch als LSB (Least Significant Bit) bezeichnet.
Das Bit mit der kleinsten Wertigkeit. Bit 31 aus einem Word wird auch als
MSB (Most Significant Bit) bezeichnet. Das Bit mit der größten
Wertigkeit. Die Zählweise ist von links nach rechts und von 0 bis 63.
Daraus läßt sich gleich die Wertigkeit der einzelnen Bits berechnen:
Bit |
Exponent |
Wertigkeit |
|
Bit |
Exponent |
Wertigkeit |
0 |
20 |
1 |
|
32 |
232 |
4294967296 |
1 |
21 |
2 |
|
33 |
233 |
8589934592 |
2 |
22 |
4 |
|
34 |
234 |
17179869184 |
3 |
23 |
8 |
|
35 |
235 |
34359738368 |
4 |
24 |
16 |
|
36 |
236 |
68719476736 |
5 |
25 |
32 |
|
37 |
237 |
137438953472 |
6 |
26 |
64 |
|
38 |
238 |
274877906944 |
7 |
27 |
128 |
|
39 |
239 |
549755813888 |
8 |
28 |
256 |
|
40 |
240 |
1099511627776 |
9 |
29 |
512 |
|
41 |
241 |
2199023255552 |
10 |
210 |
1024 |
|
42 |
242 |
4398046511104 |
11 |
211 |
2048 |
|
43 |
243 |
8796093022208 |
12 |
212 |
4096 |
|
44 |
244 |
17592186044416 |
13 |
213 |
8192 |
|
45 |
245 |
35184372088832 |
14 |
214 |
16384 |
|
46 |
246 |
70368744177664 |
15 |
215 |
32768 |
|
47 |
247 |
140737488355328 |
16 |
216 |
65536 |
|
48 |
248 |
281474976710656 |
17 |
217 |
131072 |
|
49 |
249 |
562949953421312 |
18 |
218 |
262144 |
|
50 |
250 |
1125899906842624 |
19 |
219 |
524288 |
|
51 |
251 |
2251799813685248 |
20 |
220 |
1048576 |
|
52 |
252 |
4503599627370496 |
21 |
221 |
2097152 |
|
53 |
253 |
9007199254740992 |
22 |
222 |
4194304 |
|
54 |
254 |
18014398509481984 |
23 |
223 |
8388608 |
|
55 |
255 |
36028797018963968 |
24 |
224 |
16777216 |
|
56 |
256 |
72057594037927936 |
25 |
225 |
33554432 |
|
57 |
257 |
144115188075855872 |
26 |
226 |
67108864 |
|
58 |
258 |
288230376151711744 |
27 |
227 |
134217728 |
|
59 |
259 |
576460752303423488 |
28 |
228 |
268435456 |
|
60 |
260 |
1152921504606846976 |
29 |
229 |
536870912 |
|
61 |
261 |
2305843009213693952 |
30 |
230 |
1073741824 |
|
62 |
262 |
4611686018427387904 |
31 |
231 |
2147483648 |
|
63 |
263 |
9223372036854775808 |
Der Wertebereich besteht nur aus positiven Zahlen von 0 bis
18.446.744.073.709.551.615
| Hex |
Dez |
| $0000000000000000 |
0 |
| ... |
... |
| $7FFFFFFFFFFFFFFF |
9223372036854775807 |
| $8000000000000000 |
9223372036854775808 |
| ... |
... |
| $FFFFFFFFFFFFFFFF |
18446744073709551615 |