skip to main content

kiesler.at

Alpha C Inline-Assembler
updated by rck, 2004-10-08

C war schon seit Anfang an eine sehr maschinennahe Programmiersprache. Dadurch entstanden einerseits Probleme wie Bufferoverflows ('effizientes' Speichermanagement). Andererseits wichtige Konzepte wie Inline-Assembler. Inline-Assembler ist oft nicht nur einfacher zu durchschauen, weil der C-Compiler das ,,Housekeeping'' (Adressen-Ausrichtung, etc.) macht. Sondern auch fast so effizient wie ,,pure Assembler''.
1 | 2 | 3 | 4 | 5 | 6

Inline Assembler in C?

In C gab es schon lange vor Turbo Pascal Inline-Assembler. Es gibt mindestens zwei Arten von C-Inline-Assembler (wenn nicht mehr); ich m�chte hier die f�r die �bersetzerbau-�bung auf der TU-Wien relevante Variation vorstellen.

Ein Beispiel
01: unsigned long count0s(unsigned long a) {
02:    unsigned long i, r=0;
03:
04:    asm volatile(
05:      "not %1, %0 \n\t"
06:      "ctpop %0, %0 \n\t":
07:      "=r"(r): "r"(a)
08:    );
09:    return(r);
10: }

Das ist das asma Beispiel aus der �bersetzerbau-�bung im Sommersemester 2004, mit Inline-Assembler gel�st.

Interessant sind die Zeilen 04-08, ich werde gleich auf sie eingehen.

Der Inline-Assemblerblock

Ein Inline-Assemblerblock f�r GCC auf der Alpha beginnt mit "asm volatile". Asm ist klar, steht f�r Assembler. Aber volatile? Volatile hei�t soviel wie: Bitte, lieber Compiler, lass den Code so wie er ist und tu ihn nicht weiter optimieren.

Volatile kann �brigens auch bei Variablen verwendet werden. Die werden dann auf jedenfall von C verwendet, auch wenn sie wegoptimiert werden k�nnten. Kann beim Debugging n�tzlich sein.

Schreib- und Leseregister

Ich gehe nicht der Reihe nach vor, sondern springe gleich zu Zeile 07. "=r"(r) hei�t soviel wie: Ich m�chte mir einen Register reservieren, dessen Wert im Anschlu� an den asm volatile Block in Variable r landet.

"=" steht f�r Schreibzugriff, das erste "r" f�r Register und das "(r)" f�r Variable r. Die wurde in Zeile 02 mir unsigned long r=0 definiert.

Gleich neben unserem Schreibregister finden wir noch ein Leseregister, es ist in unserem Fall der �bergabeparameter a. Man beachte das Fehlende =.

Die Schreib- und Leseregister werden vom Compiler durchnummeriert. Der allererste Register ist in unserem Fall der, in dem wir die Variable r speichern. Er bekommt die Bezeichnung %0. Der zweite Register wird mit dem Wert vom �bergabeparameter a initialisiert, er erh�lt Bezeichnung %1.

Inline-Assembler Sections

Wir haben in einem Inline-Assembler Block drei Sections (ich nenne die einfach mal so, ist keine offizielle Bezeichnung) die durch ":" getrennt werden. Die beiden letzten, die Schreib- und Leseregisterdeklaration hatten wir bereits. Jetzt zum Hauptdarsteller, den Assemblerstatements.

Im wesentlichen ist hier unser Assembler-Programm, in einer sehr puristischen Form. In Zeile 05 negiert not den �bergabeparameter a und sichert ihn in r. In Zeile 06 z�hlt der Alphaprozessor mit ctpop die Anzahl der Einsen -- die Urspr�nglich ja alle Nuller waren -- und schreibt das Ergebnis wieder nach r (zumindest im logischen Ablauf, praktisch passiert das alles mit Registern!).

Interessantes Detail hier vielleicht die \n\t Kombinationen gegen Zeilenende. Wozu? Aus Kosmetik-gr�nden und der �bersicht wegen. Sieht man n�mlich im Anschluss an den Sourcecode (erhalten wir mit gcc -mcpu=ev6 -S -O inline.c), sind dort die Zeilen in Reih' und Glied ausgerichtet.

Der erzeugte Assemblercode

        .file 1 "inline.c"
        .set noat
        .set noreorder
        .arch ev6
.text
        .align 5
        .globl count0s
        .ent count0s
count0s:
        .frame $30,0,$26,0
$count0s..ng:
        .prologue 0
        not $16, $0
        ctpop $0, $0

        ret $31,($26),1
        .end count0s
        .ident "GCC: (GNU) 2.95.2 19991024 (release)"

1 | 2 | 3 | 4 | 5 | 6



RSSComments - Make a comment
The comments are owned by the poster. We are not responsible for its content.
  • Eleganter

    Posted on 2004-05-22 01:25:06 By rck[110]

    static inline long
    __attribute__ ((unused))
    count_population (volatile long val)
    {
    long ret;

    __asm__ __volatile__ (
    "ctpop %1,%0\n\t"
    : "=&r"(ret)
    : "r"(val));

    return ret;
    }

    So meinte ich das im Informatikforum. Wof�r das attribute(unused) ist, wei� ich auch nicht genau, aber bei der glibc wird's immer so geschrieben, wird schon nicht so falsch sein.

    Und bei deinem ersten Beispiel w�rd ich das "not" weglassen und stattdessen bei den Eingangs-Constraints einfach ~a statt a schreiben - das gibt dem Compiler mehr Freiheit zu optimieren, wenn ihm danach ist.

    [Reply ]

RSSAll Articles
2008, 2007, 2006, 2005, 2004

What's Related

Documents

�bersetzerbau

Link Manager

�bersetzerbau
Programming

Article Manager

�bersetzerbau
Programming

FAQ

�bersetzerbau

Photo Albums

Programming

RSS News Feeds

Programming

Announcements

Programming

Web Pages

Programming

Latest Updates

AdministrativeTexts
updated by freddiemac1993, 2013-06-14
wiki

Re: adventures
created by brittdavis10, 2012-02-23 (1 rply, 3 views)
thread

Re: how to run phpwebsite...
created by alexander, 2011-08-25 (2 rpls, 3607 views)
thread

Re: Forum tags
created by HaroldFaragher, 2011-08-22 (3 rpls, 8488 views)
thread


Zu den KO2100 Foren