sprungbefehler mit 8051

Gast #1927799
Lesenswert?

Guten Abend,

bei diesem Programmausschnitt funktioniert etwas nicht so, wie es sein 
soll. Wenn der Wert 00h im speicherplatz wert steht, soll zur Marke1 
gesprungen werden. Dies funktioniert auch. Ebenfalls funktioniert ein 
Sprung zur Marke2, wenn 01h im Speicher wert steht. Die weiteren Sprünge 
also mit 03h, 04h, ... funktionieren einfach nicht. Für Hilfe bin ich 
Euch dankbar!
1
    mov     A,wert
2
    cjne    A,#01h,carry_check
3
    inc     A
4
    jmp     springen
5
carry_check:
6
    jc      springen
7
                         
8

9
multiplizieren:
10
    clr     cy
11
    mul     AB                      ;multipliziere den Inhalt von A Register mit B Register
12
    jnb     OV,Temperaturueberwachung
13
 
14

15
springen:
16
    mov     dptr,#Marke1            
17
    jmp     @A+dptr  
18
               
19
Marke1:
20
jmp     Programm1
21
Marke2:
22
jmp     Programm2
23
Marke3:
24
jmp     Programm3
25
Marke4:
26
jmp     Programm4
27
Marke5:
28
jmp     Programm5
29
Marke6:
30
jmp     Programm6

freundliche Grüße
Daniel
Gast #1927815
Lesenswert?

Hallo Daniel,
soweit ich mich noch an 8051 erinnern kann sind die "JMP xyz"'s doch 2 
Byte lang.

    mov     A,wert
    add     A,A          ; falls das so einfach geht
    mov     dptr,#Marke1
    jmp     @A+dptr      ; genauer JMP @(2*wert)+DPTR

Marke1:
jmp     Programm1
Marke2:
jmp     Programm2
Marke3:
jmp     Programm3
Marke4:
jmp     Programm4
Marke5:
jmp     Programm5
Marke6:

So könnte es besser gehen ;-)

Gruß,
Jürgen
Gast #1927835
Lesenswert?

Je nachdem, ob der JMP-Befehl in eine 2- oder 3-Byte Folge übersetzt 
wird, muß der Wert im Akku verdoppelt oder verdreifacht werden.

Beispiel (2-Byte JMP = AJMP):

Akku = 0 verzweigt zur Marke1
Akku = 2 verzweigt zur Marke2
Akku = 4 verzweigt zur Marke3

usw. und entsprechend für 3-Byte JMP-Befehl LJMP.
Gast #1927858
Lesenswert?

Die verschiedenen Marken  liegen ziemlich sicher nicht über 0ffh wenn du 
das meinst, MaWin? Ich habe es nun so ähnlich probiert, wie Jürgen es 
meinte, jedoch ohne Erfolg. Liegt es vielleicht doch daran, dass man bei 
der Addition von Akku und dptr etwas berücksichtigen muss?
1
    mov     A,wert
2
    cjne    A,#01h,addition
3
    jmp     Sprungverteiler
4
addition:
5
    mov     A,wert
6
    add     A,@R0         ;R0 zeigt auf wert
7

8
Sprungverteiler:
9
    mov     dptr,#Marke1
10
    jmp     @A+dptr      ; genauer JMP @(2*wert)+DPTR
11

12
Marke1:
13
jmp     Programm1
14
Marke2:
15
jmp     Programm2
16
Marke3:
17
jmp     Programm3
18
Marke4:
19
jmp     Programm4
20
Marke5:
21
jmp     Programm5
22
Marke6:
23
jmp     Programm6
Gast #1927921
Lesenswert?

ok, vielen Dank schon mal!
wie ich es nun programmieren muss, habe ich nun verstanden
mit null und eins funktioniert es schon, jedoch habe ich noch probleme 
bei der multiplikation mit 02h. ich habe das leider noch nie gemacht. 
Der inhalt von A und B - Register(2) soll multipliziert werden und im 
LSB und dem nächsthöherem bit aufscheinen. Es handelt sich nur um kleine 
werte.
1
multiplizieren:
2
    mov     B,#02h
3
    mov     A,wert
4
    clr     cy
5
    mul     AB 
6
    mov     dptr,#Mahlen
7
    jmp     @A+dptr     
8
;............    
9
;..........

MfG
Daniel
#1928020
Lesenswert?

Einen andere Möglichkeit ist, die Sprungadresse aus der Tabelle zu 
lesen.
Du solltest auch einen Test vornehmen, ob überhaupt ein Sprungziel da 
ist. Sonst springst Du ins Nirwana und wunderst Dich, was Dein Programm 
macht.
1
; Input: A = Index (0..255)
2
jump_to_program:
3
        cjne    a, #(tab_end - tab_start) / 2, _jtb1    ; error check
4
_jtb1:  jnc     error
5
        mov     dptr, #tab_start
6
        add     a, acc                  ; * 2
7
        jnc     _jtb2
8
        inc     dptr                    ; handle carry
9
_jtb2:  mov     r7, a
10
        movc    a, @a+dptr              ; get high byte
11
        xch     a, r7
12
        inc     a
13
        movc    a, @a+dptr              ; get low byte
14
        mov     dph, r7
15
        mov     dpl, #0
16
        jmp     @a+dptr
17

18
error:                                  ; error handler: index out of table
19
        ret
20

21
tab_start:
22
        dw      pr1, pr2, pr3, pr4
23
tab_end:
24

25
pr1:    ret
26
pr2:    ret
27
pr3:    ret
28
pr4:    ret


Peter
#1930100
Lesenswert?

Peter Dannegger schrieb:
> Fox Mulder schrieb:
>> Eine Multiplikation des Akku mit 2 entspricht dann "RL A".
>
> Dann mußt Du CY aber vorher löschen.
> Schneller geht daher "ADD A, ACC".

Das stimmt so nicht ganz.

Ich habe ja explizit den RL Befehl genommen, welcher nicht das Carry Bit 
berücksichtigt im Gegensatz zu RLC.
"RL A" ist ebenfalls wie "ADD A, ACC" ein 1 Machinenzyklus Befehl, aber 
"RL A" benötigt nur ein Byte wohingegen der "ADD A, ACC" 2 Byte 
Speicherplatz benötigt.
Sogesehen sind beide Befehle zwar gleich schnell, aber der RL braucht 
nur 50% des Speichers. ;)

Ciao,
     Rainer

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren