Archiv verlassen und diese Seite im Standarddesign anzeigen : If else in Assembler
Hi,
wie setzte ich den Basic Code in Assembler um?
Der Code sollte so schnell wie möglich ablaufen.
If G_erase = 1 Then
Gl_rstflag = 1
Else
Gl_rstflag = 0
End If
Danke
Kommt sehr auf die Daten-Typen an (Byte , Word, etc.)
schau dich da mal um:
http://www.rn-wissen.de/index.php/Assembler_Einf%C3%BChrung_f%C3%BCr_Bascom-User#Verzweigen
Hi,
Danke.
das ist alles in Byte.
So geht es. Ist sogar etwas schneller.
Geht das vielleicht noch schneller? #-o
$asm
LDs R25, {G_erase} '
LDI R24, 1 ' R24 = 1
CP R25, R24
BREQ Label_1 ' Verzweigen nach "Ziel", wenn R25 = R24
LDI R22, 0 ' das machen wir (zum Beispiel), wenn R25 NICHT= r24 ist
RJMP Label_2 'wir müssen unbedingt springen, sonst laufen wir ja
Label_1:
LDI R22, 1 ' das machen wir (zum Beispiel), wenn R25 = r24 ist
Label_2:
sts {Gl_rstflag} , R22
$end Asm
Besserwessi
27.09.2010, 18:23
Das geht noch einiges schneller. Für den Vergleich mit Konstanten gibt es z.B. den Befehl CPI. Statt eine IF then else kann man es auch leich umschreiben auf nur eine Verzweigung, indem man erst ein register mit 0 läd, dann den Vergleich macht und ggf die 1 durch eine 0 ersetzt. Dann kann man den Registerinhalt zurückschreiben.
Da hier nur ein Befehl über sprungen wird kann man auch statt dem Sprung ein Skipbefehl genutzt werden.
Als Besonderheit gibt es dann noch den Befehl SPSE für ein ganz besonder kurze Lösung.
Also etwa so:
ldi R24 , 1
lds R25, Variable1
CPSE R24,R25
ldi R24,0
STS Varaible2, R24
Cool danke.
Das teste ich gleich mal.
Hi,
super, nur diese eine Funktion macht fast 0,6% aus.
Das hört sich nicht vielleicht nicht vile an, aber wenn ich alles austausche dann wird das GLCD immer schneller.
Das Programm ansich ist mir egal wie lange das dauert, das bekokmme ich auch nicht mit. Ob die Temperaturberechung 0.01sec. schneller ist als vorher spielt ja kene Rolle bei einer Wetterstation.
Aber die Anzeige sehe ich.
Bei genauerer Betrachtung der Aufgabenstellung brauchst du gar kein "IF", sondern nur den "1"-er oder "0"-er von G-erase nach G_rstflag zu übertragen.
$asm
LDS R25, {G_erase}
ANDI R25, 1 ' alles ausser 1 wegmaskieren
STS {Gl_rstflag} , R25
' that's it
$end Asm
Cool. Danke.
Geht noch schneller.
Bald habe ich gar keinen Code mehr. ](*,)
Noch ne Frage
In Bascom gibt es den Befehl MOD.
Ich habe z.B. die Funktion Mod8 verwendet.
Ich habe das in dies hier verändert.
Stimmt das so?
$asm
lds R24, {Gl_x}
Mod8:
subi r24, 80
brcs rest8
subi r24, 80
brpl sub8
Rest8:
subi r24, -80
Sub8:
subi r24, 8
brpl sub8
subi r24, -8
Mod8_exit:
LDI R25, 7
!sub r25, r24
sts {Gl_bit} , R25
$end Asm
Wenn du den 8-er Rest brauchst,
$asm
LDS R25, {Gl_x}
ANDI R25, 7 ' alles ausser 0-7 wegmaskieren
STS {Gl_bit} , R25
' that's it
$end Asm
Bei Werten, die keine 2-er Potenzen sind, musst du allerdings meist wirklich durch die Gegend dividieren
Besserwessi
28.09.2010, 20:00
Die Version mit dem ANDI für das orignal Problem ist nicht zu 100% das gleiche wie der original BASIC Code. Wenn da z.B. der Wert 3 vorkommt, macht der original Code daraus eine 0 die Version mit dem ANDI eine 1. Es gibt aber Fälle wo es so geht.
Hi,
ich habe noch was.
Wie setzte ich das um.
Das geht doch mit
in R16, PIND ; lies den Eingang von Port D
oder?
Aber wie geht das dann das .gl_bit gesetzt wird und die anderen Port's nicht überschrieben werden?
Gl_inp Alias Pina 'LCD data input
Gl_tris Alias Ddra 'LCD data redirection
Dim Gl_bit As Byte
Dim Gl_rstflag As Byte
Dim Gl_pix As Byte
Gl_tris = &B00000000 'Port input
Gl_read = Gl_inp 'laden
Gl_tris = &B11111111 'port output
If Gl_rstflag = 0 Then
Set Gl_read.gl_bit
Else
Reset Gl_read.gl_bit
End If
Gl_pix = Gl_read
end
da gl_bit eine BitNUMMER von 0 - 7 ist, du aber für das setzen eine BitMASKE brauchst, musst du letztere erstmal durch links-shiften eines 1-ers (gl_bit mal) konstruieren. dann kannst du mit OR setzen.
oder Maske invertieren und mit AND löschen
ein Beispiel für das konvertieren findest du bei
http://www.rn-wissen.de/index.php/Bascom_Inside-Code#PULSEIN
$asm
.equ Gl_tris_asm = Ddra
$end Asm
lds R20,{Gl_bit}
!cbi Gl_tris_asm, 3 '; löscht das Bit 3 in DDRA
Das geht so.
Aber ich kann jetzt nicht die 3 durch die R20 ersetzen.
LDS r24 , {Gl_bit}
L_0x00F6:
LDI r25,0x01 ' 1-er laden
AND r24,r24 ' gl_bit = 0 ?
BREQ L_0x0104 ' dann fertig
CLC ' clear carry
L_0x00FE:
ROL r25 ' rot left
DEC r24 ' bit-nr - 1
BRNE L_0x00FE ' fertig ?
L_0x0104:
'-------------------------------------------------------------------------
LDS r23, {gl_read }
OR r23, r24 ' bit setzen
'-------------------------------------------------------------------------
COM r24 ' invertieren
AND r23, r24 ' bit löschen
'-------------------------------------------------------------------------
STS { Gl_pix } , r23
Hi,
danke.
Ich habe es mal eingebaut, aber es geht nicht.
'-----------------------------
$asm
LDS r24, {Gl_bit}
L_0x00f6:
LDI r25,0x01 ' 1-er laden
!AND r24,r24 ' gl_bit = 0 ?
BREQ L_0x0104 ' dann fertig
CLC ' clear carry
L_0x00fe:
ROL r25 ' rot left
DEC r24 ' bit-nr - 1
BRNE L_0x00FE ' fertig ?
L_0x0104:
LDS r23, {gl_read}
COM r24 ' invertieren
$end Asm
If Gl_rstflag = 1 Then
!OR r23, r24 ' bit setzen
Else
!AND r23, r24 ' bit löschen
End If
!STS {Gl_pix}, r23
'-----------------------------------------------------
Was mache ich falsch.
LDS r23, {gl_read}
$end Asm
If Gl_rstflag = 1 Then
!OR r23, r24 ' bit setzen
Else
COM r24 ' invertieren
!AND r23, r24 ' bit löschen
End If
!STS {Gl_pix}, r23
Hi,
sorry, aber es will nicht.
'-----------------------------
Gl_read = Gl_inp 'PIND 'Assign data
Gl_tris = &B11111111 'port output
$asm
LDS r24, {Gl_bit}
L_10x00f6:
LDI r25,0x01 ' 1-er laden
!AND r24,r24 ' gl_bit = 0 ?
BREQ L_10x0104 ' dann fertig
CLC ' clear carry
L_10x00fe:
ROL r25 ' rot left
DEC r24 ' bit-nr - 1
BRNE L_10x00FE ' fertig ?
L_10x0104:
LDS r23, {gl_read}
$end Asm
If Gl_rstflag = 1 Then
!OR r23, r24 ' bit setzen
Else
COM r24 ' invertieren
!AND r23, r24 ' bit löschen
End If
!STS {Gl_pix}, r23
'-------------------------------
sry, waren fehler drin.
das hier jedenfalls hab ich getestet, das tut, wie es soll.
Gl_rstflag = 1 ' zum testen
Gl_bit = 3 ' zum testen
$asm
LDS r24, {Gl_bit}
L_10x00f6:
ldi r25, &H01
!AND r24,r24 ' gl_bit = 0 ?
BREQ L_10x0104 ' dann fertig
CLC ' clear carry
L_10x00fe:
ROL r25 ' rot left
DEC r24 ' bit-nr - 1
BRNE L_10x00FE ' fertig ?
L_10x0104:
LDS r23, {gl_read}
$end Asm
If Gl_rstflag = 1 Then
!OR r23, r25 ' bit setzen
Else
COM r25 ' invertieren
!AND r23, r25 ' bit löschen
End If
!STS {Gl_pix}, r23
Anm: sowas wie "ldi r25, 0x01" ignoriert Bascom ohne meldung
muss aber heissen (Bascom-Style)
"ldi r25, &H01"
Hi,
also sorry, es geht nicht.
Komisch es werden keine Linien angezeigt.
So wie jetzt geht es, sobald ich Bascom Code überspringe geht es nicht.
'----------------------------------
!sbi Glcd_controll,Gl_a0_asm 'CD high
'Gl_dat = Sys_mread
!lds R20, {Sys_mread_asm}
!out Gl_dat_asm, R20
!cbi Glcd_controll,Gl_wr_asm 'WR low
! nop
!sbi Glcd_controll,Gl_wr_asm 'WR high
!cbi Glcd_controll,Gl_a0_asm 'CMD low
'! nop
'Gl_tris = &B00000000 'Port input 'Make portd input
clr R20 '&B00000000'
!out Gl_tris_asm,R20
!sbi Glcd_controll,Gl_a0_asm 'Set A0 high
!cbi Glcd_controll,Gl_rd_asm 'RD low
ser R20 '&B11111111
! nop
! nop
! nop
! nop
! nop
'Gl_read = Gl_inp 'PIND 'Assign data
in R18,Gl_inp_asm
sts {Gl_read} , R18
!sbi Glcd_controll,Gl_rd_asm 'RD high
! nop
!cbi Glcd_controll,Gl_a0_asm 'CD low high
'Gl_tris = &B11111111 'port output
!out Gl_tris_asm, R20
'--------------------------------
If Gl_rstflag = 0 Then
Set Gl_read.gl_bit
Else
Reset Gl_read.gl_bit
End If
Gl_pix = Gl_read
Goto Jumptestasm
'-----------------------------
$asm
LDS r24, {Gl_bit}
L_10x00f6:
LDI r25, &H01 ' 1-er laden
!AND r24, r24 ' gl_bit = 0 ?
BREQ L_10x0104 ' dann fertig
CLC ' clear carry
L_10x00fe:
ROL r25 ' rot left
DEC r24 ' bit-nr - 1
BRNE L_10x00FE ' fertig ?
L_10x0104:
LDs R23, {gl_read}
$end Asm
If Gl_rstflag = 1 Then
!OR r23, r24 ' bit setzen
Else
COM r24 ' invertieren
!AND r23, r24 ' bit löschen
End If
!STS {Gl_pix}, r23
'-------------------------------
Jumptestasm:
!sbi Glcd_controll,Gl_a0_asm 'CD high
!lds R20, {Sys_cur_addr_asm}
!out Gl_dat_asm, R20
'Gl_dat = Sys_cur_addr 'CSRW cmd
!cbi Glcd_controll,Gl_wr_asm 'WR low
! Nop
!sbi Glcd_controll,Gl_wr_asm 'WR high
!cbi Glcd_controll,Gl_a0_asm 'CMD low
! nop
!lds R20, {Gl_addrlo}
!out Gl_dat_asm, R20
'Gl_dat = Gl_addrlo
!cbi Glcd_controll,Gl_wr_asm 'WR low
! nop
!sbi Glcd_controll,Gl_wr_asm 'WR high
!lds R20, {Gl_addrhi}
!out Gl_dat_asm, R20
'Gl_dat = Gl_addrhi
!cbi Glcd_controll,Gl_wr_asm 'WR low
! nop
!sbi Glcd_controll,Gl_wr_asm 'WR high
!sbi Glcd_controll,Gl_a0_asm 'CD high
!lds R20, {Sys_mwrite_asm}
!out Gl_dat_asm, R20
'Gl_dat = Sys_mwrite
!cbi Glcd_controll,Gl_wr_asm 'WR low
! nop
!sbi Glcd_controll,Gl_wr_asm 'WR high
!cbi Glcd_controll,Gl_a0_asm 'CMD low
!lds R20, {Gl_pix}
!out Gl_dat_asm, R20
'Gl_dat = Gl_pix
!cbi Glcd_controll,Gl_wr_asm 'WR low
! nop
!sbi Glcd_controll,Gl_wr_asm 'WR high
!lds R20, {Gl_rstflag}
clr R20
'Gl_rstflag = 0
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.