AVR-Weiss der Kuckuck wie viel
Verfasst: Fr Jan 05, 2024 8:46 pm
Ich bin fast fertig und es tut eigentlich schon, ich zeige die Codes, ich habe nur noch ein Problem. Das hängt aber nicht mit der Sache selber zusammen. Ich zeige den ersten Code, der geht nicht, weil, wir brauchen einen Extra Stapel
Wir haben ja den Stapel für die Rekursion. Und ich habe das Buch genommen, ich zeige erst meinen Quelltext, wie ich denselben Stapel verwendet habe, das Buch sagt eindeutig, dass man keinen Stack Frame bilden kann.
Ich habe nur ein Problem, der Speicherbereich bei X ist am Anfang nicht initialisiert.
Ich habe die Daten am Anfang des Codes Segments, das ist wahrscheinlich nicht so gut, eine Änderung vollzieht aber keinen Unterschied. Der Code wurde auch so ausgeführt.
Ich habe die Lösung endlich gefunden, die ist mir schon vorher zu Augen gekommen, ich wusste nicht recht. Man muss ersten den Z Pointer verwenden und dann lpm statt ld, muss lpm verwendet werden und das geht nur mit Z Pointer. Natürlich kann man ld verwenden. das hat auch funktioniert, solange man die Daten im String dynamisch speichert. Wenn die Daten schon da stehen, dann muss man lpm verwenden.
Wir haben ja den Stapel für die Rekursion. Und ich habe das Buch genommen, ich zeige erst meinen Quelltext, wie ich denselben Stapel verwendet habe, das Buch sagt eindeutig, dass man keinen Stack Frame bilden kann.
Code: Alles auswählen
;; Das geht nicht
.include "m88def.inc"
; r3 ^= a
; r4 ^= b
; r5 ^= c
; <expr> ::= <term> 'or' <expr> | <term>
; <term> ::= <fact> 'and' <term> | <fact>
; <fact> ::= '('<expr>')' | <id> | 'not' '('<expr>')' | 'not' <id>
.cseg
boolstr: .db "(!a&!b)|(a&b)"
ldi r26, LOW(boolstr)
ldi r27, HIGH(boolstr)
ldi r16, 0
mov r3, r16
mov r4, r16
mov r5, r16
rcall expr
pop r0
ldi r16, 0xff
out DDRB, r16
pop r16
com r16
out PORTB, r16
end: rjmp end
expr:
rcall term
ld r16, X+
cpi r16, '&'
brne expr2
rcall expr
rjmp expr1
expr2:
dec r27:r26
rjmp expr3
expr1:
pop r0
pop r1
and r0, r1
push r0
expr3:
ret
term:
rcall fact
ld r16, X+
cpi r16, '|'
brne term2
rcall term
rjmp term1
term2:
dec r27:r26
rjmp term3
term1:
pop r0
pop r1
or r0, r1
push r0
term3:
ret
fact:
ld r16, X+
cpi r16, '('
brne fact_a
rcall expr
ld r16, X+
cpi r16, ')'
breq error1
rjmp fact_end
fact_a:
cpi r16, 'a'
brne fact_b
push r3
rjmp fact_end
fact_b:
cpi r16, 'b'
brne fact_c
push r4
rjmp fact_end
fact_c:
cpi r16, 'c'
brne fact_not
push r5
rjmp fact_end
fact_not:
cpi r16, '!'
brne error1
rcall expr
pop r0
com r0
push r0
fact_end:
ret
error1:
ldi r16, 1
push r16
ret
Code: Alles auswählen
;; das geht
.include "m88def.inc"
; r3 ^= a
; r4 ^= b
; r5 ^= c
; <expr> ::= <term> 'or' <expr> | <term>
; <term> ::= <fact> 'and' <term> | <fact>
; <fact> ::= '('<expr>')' | <id> | 'not' '('<expr>')' | 'not' <id>
.macro ypush
st -Y, @0
.endmacro
.macro ypop
ld @0, Y+
.endmacro
.dseg
YStapel: .byte 128
YStpAnf:
.cseg
boolstr: .db 0xff
ldi r29, HIGH(YStpAnf)
ldi r28, LOW(YStpAnf)
ldi r16, 'a'
mov r0, r16
st X, r0
ldi r27, HIGH(boolstr)
ldi r26, LOW(boolstr)
ldi r16, 1
mov r3, r16
ldi r16, 0
mov r4, r16
mov r5, r16
rcall expr
ldi r16, 0xff
out DDRB, r16
ypop r16
com r16
out PORTB, r16
end: rjmp end
expr:
rcall term
ld r16, X+
cpi r16, '&'
brne expr2
rcall expr
rjmp expr1
expr2:
dec r27:r26
rjmp expr3
expr1:
ypop r0
ypop r1
and r0, r1
ypush r0
expr3:
ret
term:
rcall fact
ld r16, X+
cpi r16, '|'
brne term2
rcall term
rjmp term1
term2:
dec r27:r26
rjmp term3
term1:
ypop r0
ypop r1
or r0, r1
ypush r0
term3:
ret
fact:
ld r16, X+
cpi r16, '('
brne fact_a
rcall expr
ld r16, X+
cpi r16, ')'
breq error1
rjmp fact_end
fact_a:
cpi r16, 'a'
brne fact_b
ypush r3
rjmp fact_end
fact_b:
cpi r16, 'b'
brne fact_c
ypush r4
rjmp fact_end
fact_c:
cpi r16, 'c'
brne fact_not
ypush r5
rjmp fact_end
fact_not:
cpi r16, '!'
brne fact_end2
rcall expr
ypop r0
com r0
ypush r0
fact_end:
ret
fact_end2:
cpi r16, ';'
brne error1
ret
error1:
ypush r16
ret
Ich habe die Daten am Anfang des Codes Segments, das ist wahrscheinlich nicht so gut, eine Änderung vollzieht aber keinen Unterschied. Der Code wurde auch so ausgeführt.
Ich habe die Lösung endlich gefunden, die ist mir schon vorher zu Augen gekommen, ich wusste nicht recht. Man muss ersten den Z Pointer verwenden und dann lpm statt ld, muss lpm verwendet werden und das geht nur mit Z Pointer. Natürlich kann man ld verwenden. das hat auch funktioniert, solange man die Daten im String dynamisch speichert. Wenn die Daten schon da stehen, dann muss man lpm verwenden.
Code: Alles auswählen
;; Verrückt, aber es scheint zu gehen, bisher ohne Klammern getestet, ich teste weiter
.include "m88def.inc"
; r3 ^= a
; r4 ^= b
; r5 ^= c
; <expr> ::= <term> 'or' <expr> | <term>
; <term> ::= <fact> 'and' <term> | <fact>
; <fact> ::= '('<expr>')' | <id> | 'not' '('<expr>')' | 'not' <id>
.macro ypush
st -Y, @0
.endmacro
.macro ypop
ld @0, Y+
.endmacro
.dseg
YStapel: .byte 128
YStpAnf:
.cseg
.org 0x00
rjmp main
main:
ldi R16, HIGH(RAMEND)
out SPH, R16
ldi R16, LOW(RAMEND)
out SPL, R16
ldi r29, HIGH(YStpAnf)
ldi r28, LOW(YStpAnf)
ldi ZH, HIGH(boolstr*2)
ldi ZL, LOW(boolstr*2)
ldi r16, 0
mov r3, r16
ldi r16, 1
mov r4, r16
mov r5, r16
rcall expr
ldi r16, 0xff
out DDRB, r16
ypop r16
com r16
out PORTB, r16
end: rjmp end
expr:
rcall term
lpm r16, Z+
cpi r16, '&'
brne expr2
rcall expr
rjmp expr1
expr2:
dec ZH:ZL
rjmp expr3
expr1:
ypop r0
ypop r1
and r0, r1
ypush r0
expr3:
ret
term:
rcall fact
lpm r16, Z+
cpi r16, '|'
brne term2
rcall term
rjmp term1
term2:
dec ZH:ZL
rjmp term3
term1:
ypop r0
ypop r1
or r0, r1
ypush r0
term3:
ret
fact:
lpm r16, Z+
cpi r16, '('
brne fact_a
rcall expr
lpm r16, Z+
cpi r16, ')'
breq error1
rjmp fact_end
fact_a:
cpi r16, 'a'
brne fact_b
ypush r3
rjmp fact_end
fact_b:
cpi r16, 'b'
brne fact_c
ypush r4
rjmp fact_end
fact_c:
cpi r16, 'c'
brne fact_not
ypush r5
rjmp fact_end
fact_not:
cpi r16, '!'
brne fact_end2
rcall expr
ypop r0
com r0
ypush r0
fact_end:
ret
fact_end2:
cpi r16, ';'
brne error1
ret
error1:
ypush r16
ret
text:
boolstr: .db "b&a", 0
Code: Alles auswählen
Allerdings, die Ausdrücke
b&a
und
b|a
Zeigen ihre Wirkung
Code: Alles auswählen
;; Es funktioniert scheinbar und es ist noch kleiner Fehler drin - der ist aber ganz klein - auch das NICHT Tut und die Klammer und alles. Nur. Das NICHT, Dreht bisher jedes Bit um. Das heisst, auch die Bits, die hinten 0 sind. Das ist letzten endes kein Fehler. aber ein unschönes Ergebnis, weil, dann leuchten alle Lämpchen
.include "m88def.inc"
; r3 ^= a
; r4 ^= b
; r5 ^= c
; <expr> ::= <term> 'or' <expr> | <term>
; <term> ::= <fact> 'and' <term> | <fact>
; <fact> ::= '('<expr>')' | <id> | 'not' '('<expr>')' | 'not' <id>
.macro ypush
st -Y, @0
.endmacro
.macro ypop
ld @0, Y+
.endmacro
.dseg
YStapel: .byte 128
YStpAnf:
.cseg
.org 0x00
rjmp main
main:
ldi R16, HIGH(RAMEND)
out SPH, R16
ldi R16, LOW(RAMEND)
out SPL, R16
ldi r29, HIGH(YStpAnf)
ldi r28, LOW(YStpAnf)
ldi ZH, HIGH(boolstr*2)
ldi ZL, LOW(boolstr*2)
ldi r16, 1
mov r3, r16
ldi r16, 1
mov r4, r16
ldi r16, 0
mov r5, r16
rcall expr
ldi r16, 0xff
out DDRB, r16
ypop r16
com r16
out PORTB, r16
end: rjmp end
expr:
rcall term
lpm r16, Z+
cpi r16, '&'
brne expr2
rcall expr
rjmp expr1
expr2:
dec ZH:ZL
rjmp expr3
expr1:
ypop r0
ypop r1
and r0, r1
ypush r0
expr3:
ret
term:
rcall fact
lpm r16, Z+
cpi r16, '|'
brne term2
rcall term
rjmp term1
term2:
dec ZH:ZL
rjmp term3
term1:
ypop r0
ypop r1
or r0, r1
ypush r0
term3:
ret
fact:
lpm r16, Z+
cpi r16, '('
brne fact_a
rcall expr
lpm r16, Z+
cpi r16, ')'
brne error1
rjmp fact_end
fact_a:
cpi r16, 'a'
brne fact_b
ypush r3
rjmp fact_end
fact_b:
cpi r16, 'b'
brne fact_c
ypush r4
rjmp fact_end
fact_c:
cpi r16, 'c'
brne fact_not
ypush r5
rjmp fact_end
fact_not:
cpi r16, '!'
brne fact_end2
rcall expr
ypop r0
com r0
ypush r0
fact_end:
ret
fact_end2:
dec ZH:ZL
ret
error1:
ldi r16, 0x01
ypush r16
ret
text:
boolstr: .db "(b&a)&!c", 0
Code: Alles auswählen
.include "m88def.inc"
; r3 ^= a
; r4 ^= b
; r5 ^= c
; <expr> ::= <term> 'or' <expr> | <term>
; <term> ::= <fact> 'and' <term> | <fact>
; <fact> ::= '('<expr>')' | <id> | 'not' '('<expr>')' | 'not' <id>
.macro ypush
st -Y, @0
.endmacro
.macro ypop
ld @0, Y+
.endmacro
.dseg
YStapel: .byte 128
YStpAnf:
.cseg
.org 0x00
rjmp main
main:
ldi R16, HIGH(RAMEND)
out SPH, R16
ldi R16, LOW(RAMEND)
out SPL, R16
ldi r29, HIGH(YStpAnf)
ldi r28, LOW(YStpAnf)
ldi ZH, HIGH(boolstr*2)
ldi ZL, LOW(boolstr*2)
ldi r16, 1
mov r3, r16
ldi r16, 1
mov r4, r16
ldi r16, 0
mov r5, r16
rcall expr
ldi r16, 0xff
out DDRB, r16
ypop r16
com r16
out PORTB, r16
end: rjmp end
expr:
rcall term
lpm r16, Z+
cpi r16, '&'
brne expr2
rcall expr
rjmp expr1
expr2:
dec ZH:ZL
rjmp expr3
expr1:
ypop r0
ypop r1
and r0, r1
ypush r0
expr3:
ret
term:
rcall fact
lpm r16, Z+
cpi r16, '|'
brne term2
rcall term
rjmp term1
term2:
dec ZH:ZL
rjmp term3
term1:
ypop r0
ypop r1
or r0, r1
ypush r0
term3:
ret
fact:
lpm r16, Z+
cpi r16, '('
brne fact_a
rcall expr
lpm r16, Z+
cpi r16, ')'
brne error1
rjmp fact_end
fact_a:
cpi r16, 'a'
brne fact_b
ypush r3
rjmp fact_end
fact_b:
cpi r16, 'b'
brne fact_c
ypush r4
rjmp fact_end
fact_c:
cpi r16, 'c'
brne fact_not
ypush r5
rjmp fact_end
fact_not:
cpi r16, '!'
brne fact_end2
rcall expr
ypop r0
com r0
ypush r0
fact_end:
ret
fact_end2:
dec ZH:ZL
ret
error1:
ldi r16, 0x01
ypush r16
ret
text:
boolstr: .db "!(b&a)&!c", 0