PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wo ist 'divmod'?



Arexx-Henk
23.04.2006, 10:40
Hallo,

Ich benutze ProgrammersNotepad2 mit Atmega8 (Asuro Roboter).

Irgendwo macht eine Teilung die ablauf von mein Program durcheinander.

z.B.

int i = EINE_CONSTANTE / eine_veriabele;


wenn ich nach compilieren die .lst Datei anscheue sehe ich etwas wie:

4104 13ee 88EC ldi r24,lo8(-56)
4105 13f0 622F mov r22,r18
4106 13f2 00D0 rcall __udivmodqi4



die function __udivmodqi4, wie oder wass oder woher komt dieser?

Im .lss Datei finde ich folgendes

00001b0c <___mulsf3x_420>:
1b0c: 01 28 or r0, r1
1b0e: 08 95 ret

00001b10 <__udivmodqi4>:
1b10: 99 1b sub r25, r25
1b12: 79 e0 ldi r23, 0x09 ; 9
1b14: 04 c0 rjmp .+8 ; 0x1b1e

00001b16 <__udivmodqi4_loop>:
1b16: 99 1f adc r25, r25
1b18: 96 17 cp r25, r22
1b1a: 08 f0 brcs .+2 ; 0x1b1e
1b1c: 96 1b sub r25, r22

00001b1e <__udivmodqi4_ep>:
1b1e: 88 1f adc r24, r24
1b20: 7a 95 dec r23
1b22: c9 f7 brne .-14 ; 0x1b16
1b24: 80 95 com r24
1b26: 08 95 ret


Was heisst dies alles, kann jemand mir dass erklaren?

Gruss

Henk

SprinterSB
23.04.2006, 11:00
__udivmodqi4 berechnet Quotient und Rest (Remainder) einer 8/8-Bit Division, und zwar als unsigned.

Die Quelle dazu steht in der libgcc2.S

Bist du sicher, daß du nicht durch 0 teilst?

Ausserdem passt das nicht zu deiner Quelle. Da steht
int = a/b;
das sollte in einem __divmodhi4 enden.

Oder hast du was an deinen Standards gedreht? (int=8Bit, int ist unsigned...)

PasstScho
23.04.2006, 12:12
Hi,
Vielleicht macht er ja int i = byte / byte;
Dann dürfte der Compiler __udivmodqi4 benutzen und es später zu int umwandeln.

MfG Alex

Arexx-Henk
23.04.2006, 17:07
Ich hab dass Problem zuruck fuhren konnen zum folgendes:

Dies ist mein program, etwas kryptisch

//glabalen variabele
volatile X;

//funktion A
fA(void){
read X;
mach_etwas();
}

//interrup1
SIGNAL_TIMER1(void){
fA();
}

//interrup2
SIGNAL_TIMER2(void){
X=200/eine_variabele; //<<---fails
Andere_Funktion(X);
}

main(){
while(1);
}


Interrupt2 dividiert und die resultatwert geht in X.
Wenn die funktion 'Andere_Funktion(X)' ausgefuhrt wird, klapt alles.
Wenn die funktion 'Andere_Funktion(X)' NICHT ausgefuhrt wird, dann wird die resultatwert vom dividierung NICHT in X plaziert.

Wass ist hier eigentlich los, oder wie kann ich dafur sorgen dass die dividierungwert ordentlich in X plaziert wird ohne diesen trick?

Gruss

Henk

SprinterSB
23.04.2006, 21:48
Ich vermute mal, der Fehler liegt woanders.

Wie sieht denn das asm aus, denn die func nixht da ist? Von X=... bis zum Ende der ISR.

Arexx-Henk
24.04.2006, 11:33
In die List file wird X immer beschrieben. Da hast Du recht, es sollte irgendwo anders liegen.
Da wird irgendwo r28 stat r18 benutzt wenn ich ein dummy funktion hinzufuge. Es kostet mich jetzt zu viel zeit dies alles zu untersuchen denn dass program ist schon ganz complex mit indexierung u.z.w.. Ich hab die dividierung mal anders gelost.
Vor ein par monaten hatte ich gleiches Problem, auch mit dividierung innerhalb einen interrupt. Vielleicht wird sich im Zukunf ergeben was die ursache ist.

Gruss

Henk

SprinterSB
24.04.2006, 18:31
Kann es sein, daß die Division in einer ISR einfach zu lange dauert, und es deshalb probleme gibt?

X ist ein 16-Bit-Wert. Greifst du atomat darauf zu? Es wird in einer ISR geändert!!!

Wenn du den Code ändert, benutzt gcc andere Register. Eben so, wie er denkt, es sei besser. Das einmal r18 genommen wird und ein andermal r28 ist mit sicherheit kein Fehler. Du musst nur *alles* anschauen, was mit diesen Registern dort angestellt wird!

Arexx-Henk
24.04.2006, 20:10
X ist ein 16-Bit-Wert. Greifst du atomat darauf zu? Es wird in einer ISR geändert!!!

Auf dem ersten Blick wurde ich sagen: dass ist vielleicht die Ursache!

Aber, vor ein paar Tagen hab ich gelernt dass interrupts die mit SIGNAL deklariert sind (so wie in meinem Program) einander NICHT unterbrechen konnen.
Ein interupt kann nur ein main() Funktion unterbrechen.
Interrupt Functionen werden immer nach einander ausgefuht. Wenn der eine fertig ist, startet die nachtse.

Da ALLE meine funktionen in interrupts stattfinden konnte es dass nicht sein.
(Die main() Funktion hat nur ein einziges 'while(1);' statement.)

Gruss

Henk

SprinterSB
24.04.2006, 22:50
Wenn deine komplette Applikation auf ISRs verteilt ist, liegt vielleicht im Gesamt-Design der Wurm? Es gibt warscheinlich mehrere ISRs, die alle zusammen Ping-Pong spielen... Wenn da eine nen Ball verpasst oder zwei mal beackert, hakt's meist an ner ganz anderen Stelle...

An den divmod-Zeug ligt's jedenfalls nicht, das funzt wie geschmiert.