Autor Thema: mem.c Asm Hilfe  (Gelesen 14339 mal)

najjannaj

  • Beiträge: 75
    • Profil anzeigen
Gespeichert
« am: 20. May 2004, 19:44 »
Hi,
Hab folgendes Problem beim Kompilieren:

mem.c: In function `count_memory':
mem.c:26: Invalid `asm' statement:
mem.c:26: fixed or forbidden register 0 (ax) was spilled for class AREG.
mem.c:34: Invalid `asm' statement:
mem.c:34: fixed or forbidden register 0 (ax) was spilled for class AREG.
mem.c:63: Invalid `asm' statement:
mem.c:63: fixed or forbidden register 0 (ax) was spilled for class AREG.

Hab keinen Plan warum das jetzt nicht funktioniert! Kann mir einer von euch Helfen???
Hier die "mem.c":

#include "include\io.h"
#include "include\mem.h"

unsigned long mem_end, bse_end;

void count_memory(void)
 {
         register unsigned long *mem;
         unsigned long mem_count, a;
         unsigned short  memkb;
         unsigned char   irq1, irq2;
         unsigned long cr0;

         /* save IRQ's */
         irq1=inportb(0x21);
         irq2=inportb(0xA1);

         /* kill all irq's */
         outportb(0x21, 0xFF);
         outportb(0xA1, 0xFF);

         mem_count=0;
         memkb=0;

         // store a copy of CR0
         __asm__ __volatile("movl %%cr0, %%eax":"=a"(cr0)::"eax");

         // invalidate the cache
         // write-back and invalidate the cache
         __asm__ __volatile__ ("wbinvd");

         // plug cr0 with just PE/CD/NW
         // cache disable(486+), no-writeback(486+), 32bit mode(386+)
         __asm__ __volatile__("movl %%eax, %%cr0" :: "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) : "eax");

         do
         {
                 memkb++;
                 mem_count+=1024*1024;
                 mem=(unsigned long *)mem_count;

                 a=*mem;

                 *mem=0x55AA55AA;
                 
                 // the empty asm calls tell gcc not to rely on whats in its registers
                 // as saved variables (this gets us around GCC optimisations)
                 asm("":::"memory");
                 if(*mem!=0x55AA55AA)
                         mem_count=0;
                 else
                 {
                         *mem=0xAA55AA55;
                         asm("":::"memory");
                         if(*mem!=0xAA55AA55)
                                 mem_count=0;
                 }

                 asm("":::"memory");
                 *mem=a;
         }while(memkb<4096 && mem_count!=0);

         __asm__ __volatile__("movl %%eax, %%cr0" :: "a" (cr0) : "eax");

         mem_end=memkb<<20;
         mem=(unsigned long *)0x413;
         bse_end=((*mem)&0xFFFF)<<6;

         outportb(0x21, irq1);
         outportb(0xA1, irq2);
 }



und hier die "mem.h":

#ifndef MEM_INCLUDE
#define MEM_INCLUDE

extern unsigned long mem_end, bse_end;

void count_memory();

#endif

kleiner

  • Beiträge: 131
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 20. May 2004, 23:15 »
Benutzt Du gcc? Dann würden die Register fehlen, die Du änderst.

najjannaj

  • Beiträge: 75
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 21. May 2004, 10:29 »
Ja, ich benutze gcc und ld, sowie nasm. Wo trag ich die Register ein und wie leg ich diese fest??
Danke!

kleiner

  • Beiträge: 131
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 21. May 2004, 17:19 »
Wenn Du bei Inline-ASM in gcc Register veränderst musst Du das dem Compiler mitteilen:
Der Compiler will Inline-ASM in folgender Form:
asm ("Assemblercode";
     : Ausgabeoperanden-Spezifikation
     : Eingabeoperanden-Spezifikation
     : Modifizierte Register
    );

Das Beispiel setzt b=a:
int move()
{
    int a = 5;
    int b;
   
    asm("mov %1, %%eax;
         mov %%eax, %0;"
         : "=r"(b) /* Ausgaberegister */
         : "r" (a)  /* Eingaberegister */
         : "%eax"); /* Modifizierte Register */

    printf("B: %u\n", b);
}
Also:
"=r" legt fest, dass für b ein Register benutzt werden soll. Das Register sucht sich der Compiler selbst aus. Angesprochen wird das erste Register, dass der Compiler auswählt mit %0. Der Inhalt des Registers soll im Anschluß in die Variable b gespeichert werden.
"r" legt fest, dass für den a ein Register benutzt werden soll. Das Register ist hier das zweite genannte, also %1.
"%eax" bedeutet hier, dass das Register %eax vom Inline-ASM benutz wird.
Und es ist egal ob man __ASM__ oder asm als Schlüsselwort verwendet.

Das Beispiel ist entnommen aus dem Anhang des Buches Linux Kernelarchitektur. http://www.linux-kernel.de/appendix/index.html

Ich hoffe ich konnte Dir helfen.

najjannaj

  • Beiträge: 75
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 23. May 2004, 17:55 »
Vielen Dank! Werd gleich Testen und dann nochmal bescheid sagen!
Danke!

 

Einloggen