Bug in microchip/xc8/v2.20/pic/sources/c90/common/awdiv.c?

OP #7606117
Lesenswert?

1
25:                while((divisor & 0x8000U) == 0) {
2
07C8  1BF1     BTFSC n, 0x7
3
07C9  2FD4     GOTO 0x7D4
4
07D3  2FC8     GOTO 0x7C8

mit Dissasambling habe ich hier diese Stelle in XC8 2.20/ C90 awdiv.c gefunden, die ja zu einer Endlosschleife führen würde, wenn Bit7= 0 ist!??

Und dann weiß ich als C-Neuling noch nicht, was 0x8000U bedeuten soll?Was bedeutet das U am Ende des Literals??

Ich arbeite gerade an einer Programmanalyse, die mir helfen sollte C-Code mit Gegenüberstellung von Assemlercode für mich begreifbarer zu machen.Also meine Praxis gleich an Mikrocontrollern, statt wie in meinem Buch mit Getränkeautomaten. Letztlich brauche ich C für Mikros, deshalb hoffe ich in der Hinsicht lehrmäßig abkürzen zu können.

Danke schon mal,hier wurde mir ja schon einige Male weiter geholfen...eine super Anlaufstelle hier!

Gruß André :)

[Edit: code-Tags eingefügt. – Mod.]

#7606441
Lesenswert?

Rudi R. schrieb:

125: while((divisor & 0x8000U) == 0) { 207C8 1BF1 BTFSC n, 0x7 307C9 2FD4 GOTO 0x7D4 407D3 2FC8 GOTO 0x7C8

mit Dissasambling habe ich hier diese Stelle in XC8 2.20/ C90 awdiv.c gefunden, die ja zu einer Endlosschleife führen würde, wenn Bit7= 0 ist!??

Nein, tut es nicht. „BTFSC Übergehe nachfolgenden Befehl, wenn Bit=0 (bit test f, skip if clear)“

Vermutlich ist es wenig hilfreich, C-Code u. Assembler zu vergleichen, wenn man beides nicht kann. Lern erst eins von beiden, oder leg dir zumindest ein Assembler-Befehlsverzeichnis zum Nachschlagen zu.

Oliver

#7606533
Lesenswert?

Volker S. schrieb:

Wenn mit BTFSC ein Befehl (der an 0x7C9) übersprungen wird, kommt man dadurch nicht nach 0x7D3 -> keine Endlosschleife!

Natürlich.

Jetzt bleibt nur die offene Frage, die sich wohl auch der TO gestellt hat, wer oder was da Bit 7 setzen sollte, wenn es ursprünglich nicht gesetzt war. Denn ohne das ist das tatsächlich eine Endlosschleife.

Dazu müsste man mal das ganze C-Programm sehen.

Oliver

#7606676
Lesenswert?

Oliver S. schrieb:

Dazu müsste man mal das ganze C-Programm sehen.

1
// integer signed division
2

3
signed int
4
#ifdef __PICC__
5
__awdiv(signed int divisor, signed int dividend)
6
#else
7
__awdiv(signed int dividend, signed int divisor)
8
#endif
9
{
10
  signed int  quotient;
11
  unsigned char  counter, sign;
12

13
  sign = 0;
14
  if(divisor < 0) {
15
    divisor = -divisor;
16
    sign = 1;
17
  }
18
  if(dividend < 0) {
19
    dividend = -dividend;
20
    sign ^= 1;
21
  }
22
  quotient = 0;
23
  if(divisor != 0) {
24
    counter = 1;
25
    while(((unsigned int)divisor & 0x8000U) == 0) {
26
      divisor <<= 1;
27
      counter++;
28
    }
29
    do {
30
      quotient <<= 1;
31
      if((unsigned int)divisor <= (unsigned int)dividend) {
32
        dividend -= divisor;
33
        quotient |= 1;
34
      }
35
      *(unsigned int *)&divisor >>= 1;
36
    } while(--counter != 0);
37
  }
38
  if(sign)
39
    quotient = -quotient;
40
  return quotient;
41
}
#7606731
Lesenswert?

Wenn das mit Optimierung übersetzt wird, ist der Bezug zwischen einzelnen Assemblersequenzen und dem C-Quellcode praktisch nicht mehr vorhanden; es ist also nicht ansatzweise klar, ob das vorher gezeigte Codeschnipsel irgendwas mit der dort als Kommentar enthaltenen Quelltextzeile zu tun hat.

Eine 1:1-Abbildung gibt es nur bei Übersetzung ohne jedwede Optimierung.

Moderator Persönliche Seite #7606773
Lesenswert?

Oliver S. schrieb:

Es ist zumindest nach dran, und das Problem mit der Endlosschleife ist nun mal im Assemblercode vorhanden.

Wenn du dir den C-Code ansiehst, solltest du erkennen können, dass die nicht endlos laufen kann. Die Schleife wird nur betreten, wenn der Divisor nicht 0 ist. Dann hat er also schon einmal mindestens ein Bit gesetzt. Dann wird in der Schleife so lange nach links geschoben, bis das höchstwertige gesetzte Bit in Bitposition 15 auftaucht. An dieser Stelle bricht sie ab.

#7606785
Lesenswert?

Jörg W. schrieb:

Dann wird in der Schleife so lange nach links geschoben, bis das höchstwertige gesetzte Bit in Bitposition 15 auftaucht. An dieser Stelle bricht sie ab.

Ja, das steht im C-Code.

Nur steht trotzdem im Assemblercode eine Schleife, die, falls das MSB im Register n nicht gesetzt ist, zur Endlosschleife wird. Jetzt kann es ja durchaus sein, daß der Fall "MSB nicht gesetzt" da vorher abgefangen wird, was dann allerdings den gezeigten Code ad absurdum führt, da nutzlos. Dafür müsste man halt den ganzen Code sehen.

Oliver

Moderator Persönliche Seite #7606788
Lesenswert?

Oliver S. schrieb:

Jetzt kann es ja durchaus sein, daß der Fall "MSB nicht gesetzt" da vorher abgefangen wird

Genau so ist es, das wird vorher abgefangen.

was dann allerdings den gezeigten Code ad absurdum führt, da nutzlos

Der gezeigte Code sind doch nur aus dem Ganzen heraus geschnipselte Teile, wie man anhand der Adressen sehen kann. Die weggeschnittenen Teile werden dann schon dafür zuständig sein, die im C-Code zu sehende Bitschubserei zu erledigen.

OP #7621372
Lesenswert?

Oh,hier ist viel passiert...und ich habe natürlich zwischendurch weiter gegrübelt und mein Programmzeug dazu klären können!...Reverse-"Ingenieering" ist schon eine lustige Sache!...aber mir sollte es hier nur helfen beide Code zu verstehen bzw. nachvollziehen zu können.Es werden definitiv beim Dissass zu viele Zwischen-Speicherungen gemacht, die man nachher im Code weglassen kann!Dienen wohl etwas zur Verwirrung, weil man ja die Optimierungen käuflich erwerben soll denke ich mal....Aber Assemler ist nach wie vor cool muss ich sagen, wenn man Fehler aufspüren will...erscheinen mir die Assembler-coder immer viel plausibler, nachvollziehbarer.Nichts desto Trotz ist C nachtürlich schneller zu schreiben und ein Unding, wenn man C nicht nutzen wollen würde.:o)...das wurde mir dann schnell bei diesem Beispiel hier auch klar!Habe jetzt aber beide Versionen davon...also mit Picas und mit XC8...nun kann ich mir das mal in Ruhe angucken und gegenüberstellen?Ich bin doch bestimmt nicht der Erste, der das so macht oder??:)

Danke für eure Beteiligung, also hier kann man schon was Fragen, hier gibts dann genügend die Ahnung haben!Das ist immer gut zu wissen.

OP #7621422
Lesenswert?

Hier habe ich mal das Projekt angehangen.(Linux Mplap X IDE v5.40 mit Pic-as (V2.30))Es ist nicht aufgeräumt, muss ich mal ran.

Ich hatte nun aus dem Disass alles in LimbreOffice-Calc copiert und dann was ich für die Picas-Datei (.s) brauchte dann wieder rübercopiert.

Die "mainDissasFromMV.s" ist die Datei, die man includen muss und dann hat man die Assembler-Version, die ich aber noch nicht komplett überprüft habe!

Vielleicht mache ich das mal in der Simulation, weil ich den Controller nicht habe.Werde das mal versuchen für einen universelleren PIC wie meinen 16F18877 umzuschreiben, da lerne ich gleich wieder mit der Doku davon umzugehen.

Also vielleicht ist das gerade für welche, die doch mal mit den Pic-as-Compiler was probieren wollen und Einsteiger sind ganz hilfreich? 2925 Codezeilen sind mit der Navigation in Mplab eigentlich noch gut überschaubar.

Hier dazu dann auch noch das Orginal von der Seite " Simple Circuit", es ist eine Realtime-clock mit Alarm und Thermometer.Das Beispiel gefiel mir ganz gut,um mal Menue-Führungen zu studieren."Button-debounce" war für mich ebenfalls interessant, scheint eine Taster-Entprellung zu sein, werde ich auch für einen anderen Code gebrauchen können.[[https://simple-circuit.com/mplab-xc8-ds3231-alarm-temperature/]]

Angehängte Dateien:
#7621823
Lesenswert?

Rudi R. schrieb:

25: while((divisor & 0x8000U) == 0) { 07C8 1BF1 BTFSC n, 0x7 07C9 2FD4 GOTO 0x7D4 07D3 2FC8 GOTO 0x7C8

Nicht Dein Ernst? Du unterschlägst Code und behauptest dann frech, das wäre ein Compilerbug. Was passiert in den Zeilen 07CA..07D2? In einer Schleife muß immer irgendwo ein Rücksprung stehen, nur eben nicht direkt nach dem Testbefehl wieder zum Test.

OP #7622155
Lesenswert?

Peter D. schrieb:

Du unterschlägst Code und behauptest dann frech, das wäre ein Compilerbug.

Die zweite Frage war ja das mit "0x8000U"...wusste noch nicht was das "U"aussagen sollte...dadurch war der Rest für mich auch noch nicht so plausibel!?

Ich hatte mich gefragt,ob es ein Bug oder Falschmeldung sein sollte? Aber hatte sich ja nun geklärt... Deshalb hatte ich hier auch die Quelle" awdiv.c" in der Frage angegeben, damit jeder,der Mplab nutz, bei sich die Datei hätte aufrufen können...Ich meinte dass es reichen würde aber muss ich dann wohl beim nächstem Mal die komplette Datei anhängen.

Was beim Disass doof ist, das alle Variablen zwischendurch wieder anders verwendet werden und man dann wirklich genau gucken muss, was gemeint ist...aber ist wohl eine Gewönungsfrage und wohl auch nix für Anfänger, die da erst einmal durchsehen müssen.

Ich denke mal wer C beherrscht, dem wird Disass nur noch selten interessieren, weil das meiste ja wohl doch hinzuhauen scheint, was der Compiler da zaubert.

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