Forum: Compiler & IDEs C in ASM umsetzen


von Jörgen (Gast)


Lesenswert?

Hi Leute
Ich kenne mich mit C nicht aus, daher wende ich mich an euch mit der
bitte um Hilfe.

Ich habe da ne Routine in C brauche es in ASM für den Atmel (mega8).
Der Quellcode hat folgenden Inhalt:

char set WL_Psum(char*buffer) reentrant
{
BYTE psum;
     psum = 0;
     while(*buffer !='\r'){
            psum+=*buffer++;
     }
     *buffer++=nibbleToA((char)((psum/16)&0x0f));
     *buffer++=nibbletoA((char)((psum)&0x0f);
     *buffer='\r';
     return(TRUE)
}

Kann mir das einer so Erklären das ich es in ASM umsetzen kann?
Danke fürs Lesen und Helfen

von Rufus T. Firefly (Gast)


Lesenswert?

Du kannst diese Funktion durch einen Compiler schicken und Dir den
Compileroutput ansehen - mit einer der vielen Kommandozeilenoptionen
vom avr-gcc (->Dokumentation) lässt sich die Ausgabe eines
kommentierten Assemblerfiles bewirken.

Wenn Du verstehen möchtest, was diese Routine macht, musst Du
allerdings auch wissen, was nibbleToA macht.
Ich hab' da aber so meine Vermutungen:

Allem Anschein zufolge bildet die Funktion die 8-bit-Prüfsumme aller
Bytes im übergebenen Puffer.
Als Pufferendezeichen wird 0x0A ('\r') ausgewertet und nicht
mitgezählt.

Diese Prüfsumme wird anscheinend in hexadezimaler Schreibweise an den
Puffer angehängt, dabei wird das erste '\r' überschrieben und nach
der Prüfsumme erneut angehängt.


Das ist kein guter Programmierstil. Keine Kommentare, keine Überprüfung
des übergebenenen Puffers oder gar dessen Länge, Verändern der
Pufferlänge ...

Und durch sparsamen Umgang mit Leerzeichen und Klammern schlecht lesbar
und missverständlich.

Besonders Klasse ist das hier

   *buffer++=nibblerToA(...);

Um zu verdeutlichen, was gemeint ist, sollten hier "Angstklammern"
verwendet werden (und Leerzeichen, die tun auch nicht weh) :

    *(buffer++) = nibbleToA(...);

Ist Dir damit geholfen?

von Jörgen (Gast)


Lesenswert?

> Ist Dir damit geholfen?
Leider Nein, und Ja es geht um eine Prüfsumme.
Ich habe kein C-Compiler um es in ASM zu übersetzen.
Wie gesagt, kenne mich mit C nicht aus.
Deshalb die Frage wie dieser Spass im ASM zu betrachten ist.
Könntest du es mal durch den Compiler jagen und mir das ASM geben?

von Tom (Gast)


Lesenswert?

Das kann er so nicht ...

dazu bräuchte er auch den restlichen Code ... Alleine deine Funktion
ruft schon wieder eine andere Funktion auf (nibbleToA) ... allein schon
hier wüsste der Compiler nicht mehr was er tun soll und abbrechen ...

von Jörgen (Gast)


Lesenswert?

Schade, aber das verstehe ich.
Mal ein Beispiel (so ist eine Vorgabe)
0x1b,0x54,0x43,0x34,0x45,0x32,0x30
Prüfsumme ist 0x38 und 0x44, nu rechne ich wie ein Dummer und komme
nicht auf das Ergebniss. Die Zeichen Binär zu Addieren (Word) und das
Ergebniss in Hex Umwandeln ergibt nicht die Prüfsumme.

von Rufus T. Firefly (Gast)


Lesenswert?

.

   "Die Zeichen Binär zu Addieren (Word) und das
   Ergebniss in Hex Umwandeln ergibt nicht die Prüfsumme."

Der Code oben macht auch nur 'ne 8-Bit-Addition, keine
16-Bit-Addition.
Also kommt auch nur 'ne 8-Bit-Prüfsumme dabei raus.
Damit ist die Prüfsumme in Deinem Beispiel mitnichten 0x38 und 0x44,
sondern 0x8D.

Die angegebenen Werte sind nur eine hexadezimale ASCII-Repräsentation
dieser 8-Bit-Zahl; der Algorithmus scheint in erster Linie dazu gedacht
zu sein, lesbare ASCII-Strings mit einer Prüfsumme zu versehen.

Eine (16-bit) Addition aller Werte Deines Beispiels ergibt den Wert
0x18d - da aber nur eine 8-Bit-Addition durchgeführt werden soll,
sollte man sich den 8-Bit-Anteil davon ansehen. Et voilà: 0x8D.

Bedenke, daß obiger Algorithmus auch noch davon ausgeht, daß der zu
prüfende String durch 0x0a terminiert sein muss und das im Puffer nach
diesem terminierenden 0x0a auch noch Platz für zwei weitere Bytes sein
muss!


   0x1b,0x54,0x43,0x34,0x45,0x32,0x30,0x0a

wird zu

   0x1b,0x54,0x43,0x34,0x45,0x32,0x30,0x38,0x44,0x0a


Wird's klarer?

von Jörg Wunsch (Gast)


Lesenswert?

> Ich habe kein C-Compiler um es in ASM zu übersetzen.

Du stellst die Frage aber im GCC-Forum.  Was hindert dich daran, dir
einen GCC zu installieren?

von AndreasH (Gast)


Lesenswert?

Ich habe die Funktion gerade mal compiliert und in asm übersetzen
lassen.

Musste das ein bischen abändern, da die gcc-syntax etwas anders ist.

Das ist der abgeänderte C-Teil:

char nibbleToA(char p) // damit keine Fehlermeldung kommt.
{
  return(p);
}

char WL_Psum(char*buffer)
{
char psum;
     psum = 0;
     while(*buffer !='\r'){
            psum+=*buffer++;
     }
     *buffer++=nibbleToA((char)((psum/16)&0x0f));
     *buffer++=nibbleToA((char)((psum   )&0x0f));
     *buffer='\r';
     return(1);
}





Das wurde daraus in asm gemacht:

.global  WL_Psum
  .type  WL_Psum, @function
WL_Psum:
/* prologue: frame size=4 */
  push r28
  push r29
  in r28,__SP_L__
  in r29,__SP_H__
  sbiw r28,4
  in _tmp_reg_,__SREG__
  cli
  out _SP_H_,r29
  out _SREG_,__tmp_reg__
  out _SP_L_,r28
/* prologue end (size=10) */
  std Y+1,r24
  std Y+2,r25
  std Y+3,__zero_reg__
.L3:
  ldd r30,Y+1
  ldd r31,Y+2
  ld r24,Z
  cpi r24,lo8(13)
  breq .L4
  ldd r24,Y+1
  ldd r25,Y+2
  mov r31,r25
  mov r30,r24
  ldd r19,Y+3
  ld r18,Z
  add r18,r19
  adiw r24,1
  std Y+1,r24
  std Y+2,r25
  std Y+3,r18
  rjmp .L3
.L4:
  ldd r24,Y+3
  std Y+4,r24
  ldd r24,Y+4
  tst r24
  brge .L5
  ldd r24,Y+4
  subi r24,lo8(-(15))
  std Y+4,r24
.L5:
  ldd r24,Y+4
  asr r24
  asr r24
  asr r24
  asr r24
  andi r24,lo8(15)
  rcall nibbleToA
  mov r18,r24
  ldd r24,Y+1
  ldd r25,Y+2
  mov r31,r25
  mov r30,r24
  st Z,r18
  adiw r24,1
  std Y+1,r24
  std Y+2,r25
  ldd r24,Y+3
  andi r24,lo8(15)
  rcall nibbleToA
  mov r18,r24
  ldd r24,Y+1
  ldd r25,Y+2
  mov r31,r25
  mov r30,r24
  st Z,r18
  adiw r24,1
  std Y+1,r24
  std Y+2,r25
  ldd r30,Y+1
  ldd r31,Y+2
  ldi r24,lo8(13)
  st Z,r24
  ldi r24,lo8(1)
  ldi r25,hi8(1)
/* epilogue: frame size=4 */
  adiw r28,4
  in _tmp_reg_,__SREG__
  cli
  out _SP_H_,r29
  out _SREG_,__tmp_reg__
  out _SP_L_,r28
  pop r29
  pop r28
  ret

Durchkämpfen musst Du Dich alleine.

Grüße
Andreas

von Rufus T. Firefly (Gast)


Lesenswert?

Wäre es nicht hilfreich, bei so einem Beispiel den Compiler zu
instruieren, die C-Sourcezeilen als Kommentare in das Assemblerlisting
einzufügen?

von AndreasH (Gast)


Lesenswert?

Wie geht das?
Ich hätte das letzlich gerne auch mal gehabt, kenne aber nur -S als
Option.

von Jörgen (Gast)


Lesenswert?

@Jörg Wunsch
>Was hindert dich daran, dir einen GCC zu installieren?
Das beantwortet:
>AndreasH
>...Musste das ein bischen abändern....damit keine Fehlermeldung
kommt.

Nur wer C kann, kann es auch ändern. Die beste Soft nutzt nix, wenn man
sich damit nicht auskennt.

Ihr habt auf alle Fälle eine große Hilfe geleistet.
Danke euch.

von OldBug (Gast)


Lesenswert?

btw, was Rufus schon erkannt hat, aber in dem Code völlig fehlt:

nibbleToA; nibble to ASCII; wandelt ein Nibble in seine
ASCII-representation in Ziffern und Buchstaben. Das wird ihm wohl auch
noch komplett fehlen...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.