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
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?
> 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?
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 ...
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.
. "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?
> 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?
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
Wäre es nicht hilfreich, bei so einem Beispiel den Compiler zu instruieren, die C-Sourcezeilen als Kommentare in das Assemblerlisting einzufügen?
Wie geht das? Ich hätte das letzlich gerne auch mal gehabt, kenne aber nur -S als Option.
@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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.