AVR-Weiss der Kuckuck wie viel

Antworten
Benutzeravatar
davidvajda.de
Site Admin
Beiträge: 1424
Registriert: Di Jul 18, 2023 8:36 pm
Wohnort: D-72072, Tübingen
Kontaktdaten:

AVR-Weiss der Kuckuck wie viel

Beitrag von davidvajda.de »

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.

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 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.

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
Antworten