Autor Thema: Inline-Assembler  (Gelesen 5003 mal)

NoeTrimm

  • Beiträge: 36
    • Profil anzeigen
Gespeichert
« am: 22. April 2008, 10:13 »
Einen wunderschönen guten morgen,

ich bin nun gerade dabei die Funktionen memcpy und setmem in meinen C-Kernele einzubauen und hab mir dazu mal den Artikel im Wiki "Inline-Assembler mit gcc" durchgelesen.
Aber so ganz hab ich einiges nicht verstanden.

Hier mal das was ich bisher getipselt habe:
void memcpy(void *Src, void *Dest, unsigned int iByteCount) {
asm(
"push (%ebp)";
"mov %esp, %ebp";
// sichern
"push (%ecx)";
"push (%edx)";
"push (%edi)";
"push (%esi)";
// Quelladresse nach ESI
"mov esi, [ebp+8]";
// Zieladresse nach EDI
"mov edi, [ebp+12]";
// Anzahl der Bytes nach ECX
"mov ecx, [ebp+16]";
// ECX nach EDX kopieren
"mov %ecx, %edx";
// Ersten beiden Bits in ECX löschen um durch 4 teilbare Zahl zu erhalten
"and 0xFFFFFFFC, %ecx";
// ECX durch 4 dividieren
"shr %2, %ecx";
// DWORDS kopieren
"rep movsd";
// EDX wieder nach ECX kopieren
"mov %edx, %ecx";
// Alle Bits bis auf die ersten beiden löschen
"and %3, %ecx";
// BYTES kopieren
"rep movsb";
// holen
"pop (%esi)";
"pop (%edi)";
"pop (%edx)";
"pop (%ecx)";
"mov %ebp, %esp";
"pop (%ebp)";
: : );
}

Bis zur Quelladresse müsste es ja richtig sein. von da an wusst ich nicht weiter wie ich [ebp+8] umschreibe in Inline-Assembler. Das ich Quell und zielreg noch vertauschen muss ist mir bewusst.

Zum zweiten bin ich mir nicht sicher ob ich die Zahlen die in einige register geschrieben werdenals konstanten zu nehmen sind oder ncith und daher hab ich erstmal '%' geschrieben anstatt '$'.

Der Rest dürfte ja soweit stimmen.

Und zu guter Letzt: Die übergabe der Variablen an die Register. Es steht deshalb nix im Code, da ich das (bzw. die Syntax und parametervergabe) überhaupt nich geschnallt habe.

würde mir sehr helfen wenn ihr da mal drüber schaut.
Will ja in meinem kernel (langsam) vorankommen  :wink:

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 22. April 2008, 10:37 »
      "push (%ebp)";
Öhm, nein. Du schreibst schließlich auch nicht push [ebp] in Intel-Syntax. Davon abgesehen bist du hier in einer C-Funktion und hast deinen Stackframe schon.

Zitat
      // sichern
      "push (%ecx)";
      "push (%edx)";
      "push (%edi)";
      "push (%esi)";
Erstens falsch (s.o.) und zweitens macht gcc das für dich, wenn du Inline-Assembler benutzt wie es gedacht ist. (Für das Sichern werden die Register benutzt, die du als Eingbae, Ausgabe und in der Clobber List angegeben hast)

Zitat
      // Quelladresse nach ESI
      "mov esi, [ebp+8]";
mov 0x8(%ebp), %esi

Für den Rest, lies einfach den Artikel nochmal durch und versuch ihn dieses Mal auch zu verstehen. ;)
« Letzte Änderung: 22. April 2008, 10:44 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

NoeTrimm

  • Beiträge: 36
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 22. April 2008, 10:57 »
Ok Thanks. das hilft mir schonmal enorm weiter.

Zu dem sichern.

Heißt das ich muss garkeine register sichern??? gcc schmeißt automatisch alle, nach ': :' angegebenen Register auf den Stack und holt sie wieder?

Das mit den Klammern fand ich auch seltsam, aber stand so im Artikel. Kann aber auch sein das ich da ne info überlesen habe.

Werd nochmal drüber schauen.

 

Einloggen