Bluesmash
27.05.2008, 20:12
Hallo zusammen!
eigentlich gehört die frage auch ins assembler forum... aber die frage geht ja von bascom aus...
zu meinem problem:
ich möchte die timeraufrufe mit dem nosave befehl beschleunigen... und die unnützen pop/push befehle reduzieren...
ich habe dass compilierte .hex file mal durch einen reassembler gejagt um herauszufinden welche register in der timer isr wirklich benutzt und vorher gesichert werden müssen.
folgendes kam dabei heraus:
; reassembly of "I2C_SERVO_SLAVE.HEX"
; created by ReAVR V3.2.0
; at 2008/05/27 - 19:42:19
; for Atmel AVR assembler
;---------------------------------------
; AVR_TYPE=<unknown>
; FLASH_SIZE=8KB
; SRAM_START=0x60
;---------------------------------------
.cseg
.org 0x0000
;---------------------------------------
; byte constants:
;
.equ k00 = 0x00 ;
.equ k01 = 0x01 ;
.equ k02 = 0x02 ;
.equ k04 = 0x04 ;
.equ k07 = 0x07 ;
.equ k08 = 0x08 ;
.equ k18 = 0x18 ;
.equ k1F = 0x1F ;
.equ k33 = 0x33 ; '3'
.equ k38 = 0x38 ; '8'
.equ k40 = 0x40 ; '@'
.equ k5F = 0x5F ; '_'
.equ k60 = 0x60 ; '`'
.equ k64 = 0x64 ; 'd'
.equ k69 = 0x69 ; 'i'
.equ k83 = 0x83 ;
.equ k90 = 0x90 ;
.equ kC2 = 0xC2 ; 'Â'
.equ kE2 = 0xE2 ; 'â'
.equ kF7 = 0xF7 ; '÷'
.equ kFE = 0xFE ; 'þ'
.equ kFF = 0xFF ; 'ÿ'
;
; io register addresses:
;
.equ p09 = 0x09
.equ p0A = 0x0A
.equ p17 = 0x17
.equ p18 = 0x18
.equ p20 = 0x20
.equ p21 = 0x21
.equ p2C = 0x2C
.equ p2D = 0x2D
.equ p2E = 0x2E
.equ p2F = 0x2F
.equ p34 = 0x34
.equ p39 = 0x39
.equ p3D = 0x3D
.equ p3E = 0x3E
.equ p3F = 0x3F
;
; bit numbers:
;
.equ b0 = 0x00
.equ b1 = 0x01
.equ b2 = 0x02
.equ b3 = 0x03
.equ b4 = 0x04
.equ b5 = 0x05
.equ b6 = 0x06
.equ b7 = 0x07
;---------------------------------------
;
L0000:
jmp _reset ; L002A
; ----------- jump on last line
reti
;----------------------*
; pc=0x3(0x6)
;
nop
reti
;----------------------*
; pc=0x5(0xA)
;
nop
reti
;----------------------*
; pc=0x7(0xE)
;
nop
reti
;----------------------*
; pc=0x9(0x12)
;
nop
reti
;----------------------*
; pc=0xB(0x16)
;
nop
reti
;----------------------*
; pc=0xD(0x1A)
;
nop
reti
;----------------------*
; pc=0xF(0x1E)
;
nop
reti
;----------------------*
; pc=0x11(0x22)
;
nop
jmp L0060
; ----------- jump on last line
reti
;----------------------*
; pc=0x15(0x2A)
;
nop
reti
;----------------------*
; pc=0x17(0x2E)
;
nop
reti
;----------------------*
; pc=0x19(0x32)
;
nop
reti
;----------------------*
; pc=0x1B(0x36)
;
nop
reti
;----------------------*
; pc=0x1D(0x3A)
;
nop
reti
;----------------------*
; pc=0x1F(0x3E)
;
nop
reti
;----------------------*
; pc=0x21(0x42)
;
nop
reti
;----------------------*
; pc=0x23(0x46)
;
nop
reti
;----------------------*
; pc=0x25(0x4A)
;
nop
reti
;----------------------*
; pc=0x27(0x4E)
;
nop
reti
;----------------------*
; pc=0x29(0x52)
;
nop
;
_reset:
; L002A:
ldi r24,k5F
out p3D,r24
ldi r28,k40
ldi r30,k38
mov r4,r30
ldi r24,k08
out p3E,r24
ldi r29,k08
ldi r31,k08
mov r5,r31
ldi r30,kFE
ldi r31,k07
ldi r26,k60
ldi r27,k00
clr r24
L0039:
st X+,r24
sbiw r30,k01
brne L0039
; ----- branch on last line
ldi r24,k33
out p09,r24
ldi r24,k00
out p20,r24
ldi r24,k18
out p0A,r24
in r24,p34
mov r0,r24
andi r24,kF7
out p34,r24
ldi r24,k1F
out p21,r24
ldi r24,k07
out p21,r24
clr r6
ldi r24,k00
out p2F,r24
ldi r24,k01
out p2E,r24
in r24,p39
ori r24,k04
out p39,r24
sbi p17,b0
sbi p17,b1
sbi p17,b2
sbi p17,b3
sbi p17,b4
sbi p17,b5
sei
L0059:
ldi r24,k64
sts D0061,r24
jmp L0059
; ----------- jump on last line
cli
L005F:
rjmp L005F
; ----------- jump on last line
; pc=0x60(0xC0)
;
L0060:
push r0
push r1
push r2
push r3
push r4
push r5
push r7
push r10
push r11
push r16
push r17
push r18
push r19
push r20
push r21
push r22
push r23
push r24
push r25
push r26
push r27
push r28
push r29
push r30
push r31
in r24,p3F
push r24
lds r16,D0060
cpi r16,k00
breq L0081
; ----- branch on last line
jmp L0093
; ----------- jump on last line
L0081:
ldi r24,k00
out p2F,r24
ldi r24,k01
out p2E,r24
ldi r24,k90
ldi r25,kE2
sts (p2D+0x20),r25 ; io register
sts (p2C+0x20),r24 ; io register
sbi p18,b0
sbi p18,b1
sbi p18,b2
sbi p18,b3
sbi p18,b4
sbi p18,b5
jmp L00AB
; ----------- jump on last line
L0093:
lds r16,D0060
cpi r16,kFF
breq L0099
; ----- branch on last line
jmp L00A5
; ----------- jump on last line
L0099:
ldi r24,k00
out p2F,r24
ldi r24,k02
out p2E,r24
ldi r24,kC2
ldi r25,k69
sts (p2D+0x20),r25 ; io register
sts (p2C+0x20),r24 ; io register
jmp L00AB
; ----------- jump on last line
L00A5:
ldi r24,k83
ldi r25,kFF
sts (p2D+0x20),r25 ; io register
sts (p2C+0x20),r24 ; io register
L00AB:
lds r16,D0060
cpi r16,k00
brcs L00B2
; ----- branch on last line
breq L00B2
; ----- branch on last line
jmp L00B4
; ----------- jump on last line
L00B2:
jmp L00EA
; ----------- jump on last line
L00B4:
lds r20,D0061
lds r16,D0060
cp r16,r20
brcc L00BC
; ----- branch on last line
jmp L00BD
; ----------- jump on last line
L00BC:
cbi p18,b0
L00BD:
lds r20,D0062
lds r16,D0060
cp r16,r20
brcc L00C5
; ----- branch on last line
jmp L00C6
; ----------- jump on last line
L00C5:
cbi p18,b1
L00C6:
lds r20,D0063
lds r16,D0060
cp r16,r20
brcc L00CE
; ----- branch on last line
jmp L00CF
; ----------- jump on last line
L00CE:
cbi p18,b2
L00CF:
lds r20,D0064
lds r16,D0060
cp r16,r20
brcc L00D7
; ----- branch on last line
jmp L00D8
; ----------- jump on last line
L00D7:
cbi p18,b3
L00D8:
lds r20,D0065
lds r16,D0060
cp r16,r20
brcc L00E0
; ----- branch on last line
jmp L00E1
; ----------- jump on last line
L00E0:
cbi p18,b4
L00E1:
lds r20,D0066
lds r16,D0060
cp r16,r20
brcc L00E9
; ----- branch on last line
jmp L00EA
; ----------- jump on last line
L00E9:
cbi p18,b5
L00EA:
ldi r26,k60
ldi r27,k00
ld r24,X
subi r24,kFF
st X,r24
pop r24
out p3F,r24
pop r31
pop r30
pop r29
pop r28
pop r27
pop r26
pop r25
pop r24
pop r23
pop r22
pop r21
pop r20
pop r19
pop r18
pop r17
pop r16
pop r11
pop r10
pop r7
pop r5
pop r4
pop r3
pop r2
pop r1
pop r0
reti
;----------------------*
; pc=0x10B(0x216)
;
L010B:
sbiw r30,k01
brne L010B
; ----- branch on last line
ret
;----------------------*
; pc=0x10E(0x21C)
;
set
bld r6,b2
ret
;----------------------*
; pc=0x111(0x222)
;
clt
bld r6,b2
ret
;----------------------*
; pc=0x114(0x228)
;
; last flash byte address = 0x0227
; last flash word address = 0x0113
;---------------------------------------
.dseg
.org 0x0060
;
D0060:
.byte 1
D0061:
.byte 1
D0062:
.byte 1
D0063:
.byte 1
D0064:
.byte 1
D0065:
.byte 1
D0066:
;
; last lds/sts data byte at 0x0066
;---------------------------------------
;<eof>
wenn ich es nun richtig verstanden habe müste doch eigentlich folgendes genügen:
Timer_ISR:
push r16
push r20
push r24
push r25
in r24,p3F
push r24
------- ISR Programm -------
pop r24
out p3F,r24
pop r25
pop r24
pop r20
pop r16
Return
stimmt dies ungefähr? oder bin ich völlig falsch dran? Ich würde mich freuen wenn jemand mal drübersehen könnte...
ach ja, hier noch das original programm:
$regfile = "M32def.dat" ' the chip we use
$crystal = 16000000 ' crystal oscillator value
$baud = 19200 ' baud rate
Config Timer1 = Timer , Prescale = 1
On Timer1 Timer_irq
Enable Timer1
Config Portb.0 = Output
Servo1 Alias Portb.0
Config Portb.1 = Output
Servo2 Alias Portb.1
Config Portb.2 = Output
Servo3 Alias Portb.2
Config Portb.3 = Output
Servo4 Alias Portb.3
Config Portb.4 = Output
Servo5 Alias Portb.4
Config Portb.5 = Output
Servo6 Alias Portb.5
Dim Servo_incr As Byte
Dim Servo(6) As Byte
Dim Byte_nr As Byte
Dim I As Byte
Enable Interrupts
Do
Servo(1) = 100
Loop
End
Timer_irq:
If Servo_incr = 0 Then
Config Timer1 = Timer , Prescale = 1 '1ms 49536
Timer1 = 58000
Servo1 = 1
Servo2 = 1
Servo3 = 1
Servo4 = 1
Servo5 = 1
Servo6 = 1
Elseif Servo_incr = 255 Then
Config Timer1 = Timer , Prescale = 8 '18ms
Timer1 = 27074
Else
Timer1 = 65411 '1ms/255 65411
End If
If Servo_incr > 0 Then
If Servo_incr >= Servo(1) Then Servo1 = 0
If Servo_incr >= Servo(2) Then Servo2 = 0
If Servo_incr >= Servo(3) Then Servo3 = 0
If Servo_incr >= Servo(4) Then Servo4 = 0
If Servo_incr >= Servo(5) Then Servo5 = 0
If Servo_incr >= Servo(6) Then Servo6 = 0
End If
Incr Servo_incr
Return
Gruss BlueSmash
eigentlich gehört die frage auch ins assembler forum... aber die frage geht ja von bascom aus...
zu meinem problem:
ich möchte die timeraufrufe mit dem nosave befehl beschleunigen... und die unnützen pop/push befehle reduzieren...
ich habe dass compilierte .hex file mal durch einen reassembler gejagt um herauszufinden welche register in der timer isr wirklich benutzt und vorher gesichert werden müssen.
folgendes kam dabei heraus:
; reassembly of "I2C_SERVO_SLAVE.HEX"
; created by ReAVR V3.2.0
; at 2008/05/27 - 19:42:19
; for Atmel AVR assembler
;---------------------------------------
; AVR_TYPE=<unknown>
; FLASH_SIZE=8KB
; SRAM_START=0x60
;---------------------------------------
.cseg
.org 0x0000
;---------------------------------------
; byte constants:
;
.equ k00 = 0x00 ;
.equ k01 = 0x01 ;
.equ k02 = 0x02 ;
.equ k04 = 0x04 ;
.equ k07 = 0x07 ;
.equ k08 = 0x08 ;
.equ k18 = 0x18 ;
.equ k1F = 0x1F ;
.equ k33 = 0x33 ; '3'
.equ k38 = 0x38 ; '8'
.equ k40 = 0x40 ; '@'
.equ k5F = 0x5F ; '_'
.equ k60 = 0x60 ; '`'
.equ k64 = 0x64 ; 'd'
.equ k69 = 0x69 ; 'i'
.equ k83 = 0x83 ;
.equ k90 = 0x90 ;
.equ kC2 = 0xC2 ; 'Â'
.equ kE2 = 0xE2 ; 'â'
.equ kF7 = 0xF7 ; '÷'
.equ kFE = 0xFE ; 'þ'
.equ kFF = 0xFF ; 'ÿ'
;
; io register addresses:
;
.equ p09 = 0x09
.equ p0A = 0x0A
.equ p17 = 0x17
.equ p18 = 0x18
.equ p20 = 0x20
.equ p21 = 0x21
.equ p2C = 0x2C
.equ p2D = 0x2D
.equ p2E = 0x2E
.equ p2F = 0x2F
.equ p34 = 0x34
.equ p39 = 0x39
.equ p3D = 0x3D
.equ p3E = 0x3E
.equ p3F = 0x3F
;
; bit numbers:
;
.equ b0 = 0x00
.equ b1 = 0x01
.equ b2 = 0x02
.equ b3 = 0x03
.equ b4 = 0x04
.equ b5 = 0x05
.equ b6 = 0x06
.equ b7 = 0x07
;---------------------------------------
;
L0000:
jmp _reset ; L002A
; ----------- jump on last line
reti
;----------------------*
; pc=0x3(0x6)
;
nop
reti
;----------------------*
; pc=0x5(0xA)
;
nop
reti
;----------------------*
; pc=0x7(0xE)
;
nop
reti
;----------------------*
; pc=0x9(0x12)
;
nop
reti
;----------------------*
; pc=0xB(0x16)
;
nop
reti
;----------------------*
; pc=0xD(0x1A)
;
nop
reti
;----------------------*
; pc=0xF(0x1E)
;
nop
reti
;----------------------*
; pc=0x11(0x22)
;
nop
jmp L0060
; ----------- jump on last line
reti
;----------------------*
; pc=0x15(0x2A)
;
nop
reti
;----------------------*
; pc=0x17(0x2E)
;
nop
reti
;----------------------*
; pc=0x19(0x32)
;
nop
reti
;----------------------*
; pc=0x1B(0x36)
;
nop
reti
;----------------------*
; pc=0x1D(0x3A)
;
nop
reti
;----------------------*
; pc=0x1F(0x3E)
;
nop
reti
;----------------------*
; pc=0x21(0x42)
;
nop
reti
;----------------------*
; pc=0x23(0x46)
;
nop
reti
;----------------------*
; pc=0x25(0x4A)
;
nop
reti
;----------------------*
; pc=0x27(0x4E)
;
nop
reti
;----------------------*
; pc=0x29(0x52)
;
nop
;
_reset:
; L002A:
ldi r24,k5F
out p3D,r24
ldi r28,k40
ldi r30,k38
mov r4,r30
ldi r24,k08
out p3E,r24
ldi r29,k08
ldi r31,k08
mov r5,r31
ldi r30,kFE
ldi r31,k07
ldi r26,k60
ldi r27,k00
clr r24
L0039:
st X+,r24
sbiw r30,k01
brne L0039
; ----- branch on last line
ldi r24,k33
out p09,r24
ldi r24,k00
out p20,r24
ldi r24,k18
out p0A,r24
in r24,p34
mov r0,r24
andi r24,kF7
out p34,r24
ldi r24,k1F
out p21,r24
ldi r24,k07
out p21,r24
clr r6
ldi r24,k00
out p2F,r24
ldi r24,k01
out p2E,r24
in r24,p39
ori r24,k04
out p39,r24
sbi p17,b0
sbi p17,b1
sbi p17,b2
sbi p17,b3
sbi p17,b4
sbi p17,b5
sei
L0059:
ldi r24,k64
sts D0061,r24
jmp L0059
; ----------- jump on last line
cli
L005F:
rjmp L005F
; ----------- jump on last line
; pc=0x60(0xC0)
;
L0060:
push r0
push r1
push r2
push r3
push r4
push r5
push r7
push r10
push r11
push r16
push r17
push r18
push r19
push r20
push r21
push r22
push r23
push r24
push r25
push r26
push r27
push r28
push r29
push r30
push r31
in r24,p3F
push r24
lds r16,D0060
cpi r16,k00
breq L0081
; ----- branch on last line
jmp L0093
; ----------- jump on last line
L0081:
ldi r24,k00
out p2F,r24
ldi r24,k01
out p2E,r24
ldi r24,k90
ldi r25,kE2
sts (p2D+0x20),r25 ; io register
sts (p2C+0x20),r24 ; io register
sbi p18,b0
sbi p18,b1
sbi p18,b2
sbi p18,b3
sbi p18,b4
sbi p18,b5
jmp L00AB
; ----------- jump on last line
L0093:
lds r16,D0060
cpi r16,kFF
breq L0099
; ----- branch on last line
jmp L00A5
; ----------- jump on last line
L0099:
ldi r24,k00
out p2F,r24
ldi r24,k02
out p2E,r24
ldi r24,kC2
ldi r25,k69
sts (p2D+0x20),r25 ; io register
sts (p2C+0x20),r24 ; io register
jmp L00AB
; ----------- jump on last line
L00A5:
ldi r24,k83
ldi r25,kFF
sts (p2D+0x20),r25 ; io register
sts (p2C+0x20),r24 ; io register
L00AB:
lds r16,D0060
cpi r16,k00
brcs L00B2
; ----- branch on last line
breq L00B2
; ----- branch on last line
jmp L00B4
; ----------- jump on last line
L00B2:
jmp L00EA
; ----------- jump on last line
L00B4:
lds r20,D0061
lds r16,D0060
cp r16,r20
brcc L00BC
; ----- branch on last line
jmp L00BD
; ----------- jump on last line
L00BC:
cbi p18,b0
L00BD:
lds r20,D0062
lds r16,D0060
cp r16,r20
brcc L00C5
; ----- branch on last line
jmp L00C6
; ----------- jump on last line
L00C5:
cbi p18,b1
L00C6:
lds r20,D0063
lds r16,D0060
cp r16,r20
brcc L00CE
; ----- branch on last line
jmp L00CF
; ----------- jump on last line
L00CE:
cbi p18,b2
L00CF:
lds r20,D0064
lds r16,D0060
cp r16,r20
brcc L00D7
; ----- branch on last line
jmp L00D8
; ----------- jump on last line
L00D7:
cbi p18,b3
L00D8:
lds r20,D0065
lds r16,D0060
cp r16,r20
brcc L00E0
; ----- branch on last line
jmp L00E1
; ----------- jump on last line
L00E0:
cbi p18,b4
L00E1:
lds r20,D0066
lds r16,D0060
cp r16,r20
brcc L00E9
; ----- branch on last line
jmp L00EA
; ----------- jump on last line
L00E9:
cbi p18,b5
L00EA:
ldi r26,k60
ldi r27,k00
ld r24,X
subi r24,kFF
st X,r24
pop r24
out p3F,r24
pop r31
pop r30
pop r29
pop r28
pop r27
pop r26
pop r25
pop r24
pop r23
pop r22
pop r21
pop r20
pop r19
pop r18
pop r17
pop r16
pop r11
pop r10
pop r7
pop r5
pop r4
pop r3
pop r2
pop r1
pop r0
reti
;----------------------*
; pc=0x10B(0x216)
;
L010B:
sbiw r30,k01
brne L010B
; ----- branch on last line
ret
;----------------------*
; pc=0x10E(0x21C)
;
set
bld r6,b2
ret
;----------------------*
; pc=0x111(0x222)
;
clt
bld r6,b2
ret
;----------------------*
; pc=0x114(0x228)
;
; last flash byte address = 0x0227
; last flash word address = 0x0113
;---------------------------------------
.dseg
.org 0x0060
;
D0060:
.byte 1
D0061:
.byte 1
D0062:
.byte 1
D0063:
.byte 1
D0064:
.byte 1
D0065:
.byte 1
D0066:
;
; last lds/sts data byte at 0x0066
;---------------------------------------
;<eof>
wenn ich es nun richtig verstanden habe müste doch eigentlich folgendes genügen:
Timer_ISR:
push r16
push r20
push r24
push r25
in r24,p3F
push r24
------- ISR Programm -------
pop r24
out p3F,r24
pop r25
pop r24
pop r20
pop r16
Return
stimmt dies ungefähr? oder bin ich völlig falsch dran? Ich würde mich freuen wenn jemand mal drübersehen könnte...
ach ja, hier noch das original programm:
$regfile = "M32def.dat" ' the chip we use
$crystal = 16000000 ' crystal oscillator value
$baud = 19200 ' baud rate
Config Timer1 = Timer , Prescale = 1
On Timer1 Timer_irq
Enable Timer1
Config Portb.0 = Output
Servo1 Alias Portb.0
Config Portb.1 = Output
Servo2 Alias Portb.1
Config Portb.2 = Output
Servo3 Alias Portb.2
Config Portb.3 = Output
Servo4 Alias Portb.3
Config Portb.4 = Output
Servo5 Alias Portb.4
Config Portb.5 = Output
Servo6 Alias Portb.5
Dim Servo_incr As Byte
Dim Servo(6) As Byte
Dim Byte_nr As Byte
Dim I As Byte
Enable Interrupts
Do
Servo(1) = 100
Loop
End
Timer_irq:
If Servo_incr = 0 Then
Config Timer1 = Timer , Prescale = 1 '1ms 49536
Timer1 = 58000
Servo1 = 1
Servo2 = 1
Servo3 = 1
Servo4 = 1
Servo5 = 1
Servo6 = 1
Elseif Servo_incr = 255 Then
Config Timer1 = Timer , Prescale = 8 '18ms
Timer1 = 27074
Else
Timer1 = 65411 '1ms/255 65411
End If
If Servo_incr > 0 Then
If Servo_incr >= Servo(1) Then Servo1 = 0
If Servo_incr >= Servo(2) Then Servo2 = 0
If Servo_incr >= Servo(3) Then Servo3 = 0
If Servo_incr >= Servo(4) Then Servo4 = 0
If Servo_incr >= Servo(5) Then Servo5 = 0
If Servo_incr >= Servo(6) Then Servo6 = 0
End If
Incr Servo_incr
Return
Gruss BlueSmash