2010-06-11 13 views
8

Ist es möglich, auf 32-Bit-Register in C zuzugreifen? Wenn es ist, wie? Und wenn nicht, gibt es eine Möglichkeit, den Assembler-Code in C einzubetten? Ich benutze übrigens den MinGW-Compiler. Vielen Dank im Voraus!Ist es möglich, auf 32-Bit-Register in C zuzugreifen?

+1

erzählen Sie uns mehr über Ihre Bedürfnisse: Warum sollten Sie auf die CPU-Register zugreifen wollen ??? –

+0

können Sie indirekt die Register in Windows mit GetThreadContext und seinem Bruder SetThreadContext abrufen und setzen, ohne dass eine asm benötigt wird: http://msdn.microsoft.com/en-us/library/ms679362%28VS.85%29.aspx – Necrolis

Antwort

12

Wenn Sie das Register nur lesen möchten, können Sie einfach:

register int ecx asm("ecx"); 

Offensichtlich ist es zu Instanziierung gebunden.

Eine andere Möglichkeit ist die Inline-Montage. Zum Beispiel:

asm("movl %%ecx, %0;" : "=r" (value) :); 

Dieser speichert den ecx Wert in die Variable value. Ich habe bereits eine ähnliche Antwort here gepostet.

+0

Vielen Dank für die Codebeispiele. Genaue Information, die ich brauchte. ;) – C4theWin

1

Sie können

http://en.wikipedia.org/wiki/Inline_assembler

Beispiel aus wikipedia

extern int errno Montage in C einbetten;

int funcname(int arg1, int *arg2, int arg3) 
{ 
    int res; 
    __asm__ volatile(
    "int $0x80"  /* make the request to the OS */ 
    : "=a" (res)  /* return result in eax ("a") */ 
     "+b" (arg1),  /* pass arg1 in ebx ("b") */ 
     "+c" (arg2),  /* pass arg2 in ecx ("c") */ 
     "+d" (arg3)  /* pass arg3 in edx ("d") */ 
    : "a" (128)  /* pass system call number in eax ("a") */ 
    : "memory", "cc"); /* announce to the compiler that the memory and condition codes have been modified */ 

    /* The operating system will return a negative value on error; 
    * wrappers return -1 on error and set the errno global variable */ 
    if (-125 <= res && res < 0) { 
    errno = -res; 
    res = -1; 
    } 
    return res; 
} 
0

Ich glaube nicht, dass Sie sie direkt tun können. Sie können mit Code Inline-Assembler zu tun:

asm (
    "movl $0, %%ebx;" 
    "movl $1, %%eax;" 
); 
0

Wenn Sie auf einem 32-Bit-Prozessor und mit einem angemessenen Compiler sind, dann ja. Das genaue Mittel hängt von dem jeweiligen System und Compiler ab, für den Sie programmieren, und das wird Ihren Code natürlich so unportabel wie möglich machen.

In Ihrem Fall mit MinGW sollten Sie sich GCC's inline assembly syntax ansehen.

+1

Danke viel für den Link! Sehr hilfreich. – C4theWin

-2

Es ist im Allgemeinen nicht notwendig, auf die CPU-Register von einem Programm in einer Hochsprache zuzugreifen: Hochsprachen, wie C, Pascal, etc. genau erfunden, um die zugrunde liegende Maschine zu abstrahieren und a zu rendern Programm mehr maschinenunabhängig.

Ich vermute, dass Sie versuchen, etwas zu tun, aber keine Ahnung haben, wie man einen konventionellen Weg dazu benutzt.

Viele Zugriffe auf die Register sind in Konstrukten höherer Ebene oder in System- oder Bibliotheksaufrufen verborgen, wodurch Sie die Codierung des "dirty-part" vermeiden können. erzählen Sie uns mehr über das, was Sie tun möchten, und wir schlagen Ihnen vielleicht eine Alternative vor.

+0

Nein, ich weiß eigentlich genau, was ich mache. Aber danke, dass du mir geholfen hast. :) – C4theWin

+0

-1: Antwort ist für die Frage nicht relevant. – Sparky

0

Sie können natürlich. "MinGW" (gcc) erlaubt (wie andere Compiler) Inline-Assembly, wie andere Antworten bereits zeigen. Welche Assembly, es hängt von der CPU Ihres Systems ab (prob. 99,99%, dass es x86 ist). Dies macht jedoch Ihr Programm nicht auf anderen Prozessoren portierbar (nicht so schlecht, wenn Sie wissen, was Sie tun und warum).

Die relevante Seite, die über Versammlung für gcc spricht, ist here und here, und wenn Sie wollen, auch here. Vergessen Sie nicht, dass es nicht spezifisch sein kann, da es architekturabhängig ist (gcc kann für mehrere CPUs kompilieren)

7

Auf welche Register möchten Sie zugreifen?

Die allgemeinen Register können normalerweise nicht von C aus aufgerufen werden. Sie können Registervariablen in einer Funktion deklarieren, aber sie geben nicht an, welche spezifischen Register verwendet werden. Außerdem ignorieren die meisten Compiler das Schlüsselwort register und optimieren die Verwendung des Registers automatisch.

In Embedded-Systemen ist es oft erforderlich, auf Peripherieregister zuzugreifen (wie Timer, DMA-Controller, I/O-Pins). Solche Register sind in der Regel speicherabgebildete, so können sie von C ...

durch Definieren eines Zeigers zugegriffen werden:

volatile unsigned int *control_register_ptr = (unsigned int*) 0x00000178; 

oder durch Verwendung Vorprozessor:

#define control_register (*(unsigned int*) 0x00000178) 

Oder Sie können die Assembly-Routine verwenden.

Für die Verwendung von Assemblersprache gibt es (zumindest) drei Möglichkeiten:

  1. Eine separate .asm Quelldatei, die mit dem Programm verknüpft ist. Die Assembly-Routinen werden von C wie normale Funktionen aufgerufen. Dies ist wahrscheinlich die gebräuchlichste Methode und hat den Vorteil, dass hw-abhängige Funktionen vom Anwendungscode getrennt sind.
  2. Inline-Assembly
  3. Eigenständige Funktionen, die Anweisungen für die individuelle Assemblersprache ausführen. Dies hat den Vorteil, dass der Assemblersprachbefehl direkt auf beliebige C-Variablen zugreifen kann.
+0

Wie kannst du diese 0x00000178 Nummer bekommen? – Garmekain