Programmieren
 
 
 
 
 
C-Grundkurs
 
 
 
 
 
.. Schlüsselworte in C
 
 

 
 
 
 
 
Schlüsselworte sind solche, die in einer Programmiersprache eine besondere Aufgabe erfüllen und zusammen mit den Operationen den Befehlssatz umfassen. Sie sind deswegen reserviert und dürfen nicht für normale Bezeichnernamen verwendet werden. So ist es in C beispielsweise nicht möglich, eine Variable else zu nennen., denn else ist ein Schüsselwort, welches in der if -Verzweigung verwendet wird. (Der Variablenname Else würde funktionieren, weil in C zwischen Groß- und Kleinschreibung unterschieden wird.)
Die Liste der Schlüsselworte in C ist länger als folgend angegeben. Allerdings fehlen vorwiegend solche Schlüsselworte, die mit einem _Unterstrich beginnen. Allein aus der Kenntnis dass es sie gibt, kann man aber handeln, wenn man an einer Stelle, an der ein Name verwendet wird, dauerhaft Fehlermeldungen erhält. Einfach mal den Namen verändern.
 
 
Beispiele für Schlüsselworte sind ..
 
 

 

 

asm

continue

float

interrupt

public

switch

voilatile

 

 

auto

delete

for

long

register

template

while

 

 

break

do

friend

near

return

this

_AH

 

 

case

double

goto

new

short

typedef

_AL

 

 

catch

else

huge

operator

signed

union

_AX

 

 

char

enum

if

pascal

sizeof

unsigned

_FLAGS

 

 

class

extern

inline

private

static

virtual

usw..

 

 

const

far

int

protected

struct

void

 

 

 

 

 
 
Von diesen Schlüsselworten wurden bereits etliche in ihrer Wirkung angesprochen. Einige weitere sind hier zusammengefasst. Ein Klick in die Liste führt zum Ablageort der Beschreibung.
 
 
 
 
 

 
 
asm{...}
 
 
Es ist möglich, innerhalb eines C-Programms, Befehle der Assemblersprache unterzubringen. Dies geschieht mit dem C-Schlüsselwort asm { .. }. Tritt dieser Befehl in einem C Programm auf, wird der C-Compiler angewiesen, seine Arbeit für den Bereich der asm-Zeile oder der geschweiften Klammern zu beenden, und den Text zwischen den geschweiften Klammern als Assemblercode zu betrachten. Dieser kann nur von einem Assembler (Übersetzungsprogramm) übersetzt werden, und so ruft der Compiler ein Assemblerprogramm auf. (vorausgesetzt, es ist eines in der vorliegenden C-IDE vorhanden. Bei Borland heißt dieses Assemblerprogramm basm.exe).

Beispiel:
Das nachfolgende Programm holt per Inlineassember-Programmierung die Zeit der DOS-Uhr des Betriebssystems und gibt diese zum Bildschirm aus.
 

 

// test.cpp
// --------

#pragma option -1                   // erzeuge 80186 code
#include <STDIO.H>                  // für printf()

void main(void)
{
 char stunde, minute, sekunde;

 asm {
       mov AH, 2Ch                  // Funktion 2Ch
       int 21h                      // des SoftINT 21h -Zeit holen
       mov stunde,  CH              // Stunde  1-23
       mov minute,  CL              // Minute  0-59
       mov sekunde, DH              // Sekunde 0-59
      } 

 printf("%0.2u:%0.2u:%0.2u\r\n", stunde, minute, sekunde);
}

 

 
 
 
 
Inlineassembler-Programme besitzen den Vorteil, dass sie mit der geringsten Anzahl von Bytes ansagen können, was die CPU tun soll. Bei guter Programmierung ist ihr Overhead null wodurch sich die maximale Geschwindigkeit der CPU einstellt.
Allerdings sind Assemblerbefehle an eine bestimmte CPU gebunden, wodurch Inlineassemblerprogramme die Kompatiblität des C-Programms behindern. Dieser Aspekt ist bei Programmen für den IPC@CHIP jedoch nebensächlich, da bei ihm nur die Intel 80186 CPU auftreten kann. Bei ihm macht es Sinn, anstelle der unhandlichen und langsamen C-Interruptaufrufe, diese in Inlineassember auszuführen.
 
 
 
 
 
Grundregeln zu Inlineassembler
  • Kommentare werden auch auf den Assemblerzeilen in der Art von C geschrieben. Also // anstelle des Semikolons ; wie es bei reinen Assemblerprogrammen üblich ist.
  • Ein Inline-Assemblerprogramm kann auf die Variablen des C-Programms zugreifen. Diese müssen jedoch einen Typ besitzen, der vom benutzten CPU-Register aufgenommen und bearbeitet werden kann. So ist das AL-Register der CPU 80x86 8Bit breit. Dies korrespondiert mit dem C Variablentyp char (signed oder unsigned). Die Übertragung des Inhalts einer C int oder unsigned Variable nach AL würde zu Fehlern führen. Solche Variable können nur in 16 Bit Registern aufgenommen werden. Diese sind bei 80x86 CPUs mit einem X wie bei dem AX -Register gekennzeichnet.
  • Die Gross- und Kleinschreibung, auf die bei C-Quelltextzeilen geachtet werden muss, ist bei den Assemblerbefehlen aufgehoben. mov = MOV
  • Die Schreibweise von hexadezimalen Zahlen in Inline-Assemblerzeilen entspricht nicht der von C. Die Zahl 0x2C in C-Mnemonik wird zu 2Ch in der Assemblermnemonik. Bei Inlineassember können zudem binäre Zahlen wie 00101100b (=2Ch) angegeben werden.
    Hexadezimale Zahlen, die mit einem Buchstaben beginnen, können in Inlineassembler zu einer Irritation des Assemblerprogramms führen. Man sollte solche Zahlen grundsätzlich mit der Ziffer 0 einleiten. Anstelle E3h, besser 0E3h schreiben.
 
 
Mehr zu Inlineassembler
Will man mit Inlineassembler arbeiten, muss man über Grundwissen in Bezug auf die CPU und ihre Hardware verfügen. So beispielsweise welche Register die CPU besitzt, welche Assemblerbefehle es gibt und wie die Schnittstellen angesprochen werden können.
Mehr über die 80x86 Inline-Assemblerprogrammierung ist unter dem Menüpunkt C-Grundkurs [C und Inlineassembler] zu finden.
 
 
 
 
 
 
 
 
typedef
 
 
Bekannte Datentypen sind beispielsweise unsigned, char, int, double, .. usw. Mit dem Schlüsselwort typedef lassen sich neue Datentypen definieren. Wer beispielsweise die Nase voll hat, weil er immer ..
                          unsigned char x =0x34;
.. schreiben muss, der kann sich mit typedef einen neuen Datentyp schaffen, der die Schreiberei verkürzt.
Beispiel 1:
                          typedef unsigned char uc;
                          uc x= 0x34;

.. nach dieser Definition des neuen Datentyps uc können überall im Queltext Variable deklariert werden, die vom Typ unsigned char sind, indem uc geschrieben wird. Dieses Verfahren sieht sicherlich etwas nach der Wirkung der #define Präprozessordirektive aus und erscheint für das Beispiel auch etwas übertrieben, doch gibt es durchaus Situationen in C, wo es entspannend wirkt. Beispiele sind Strukturen, Varianten und Zeiger auf Funktionen

Beispiel 2:
           typedef struct { double x,
                            double y, } koordinate, *koordinptr;
            ...
           koordinate maximum = {12.3, 2.6};
           koordinptr maxzeiger;
           maxzeiger = &maximum;

Im Beispiel wird der Aufbau einer Struktur als Datentyp koordinate erklärt, ebenso ein Datentyp 'Zeiger auf Koordinate' koordinptr.
In der Folge können Variable oder Zeiger von diesen Datentypen abgeleitet werden, z.B. die Strukturvariable maximum, die in Beispiel bei ihrer Deklaration auch gleich definiert wird. Zuletzt wird die Adresse der Variablen maximum dem Zeiger maxzeiger, der aus dem Datentyp koordinptr abgeleitet wurde, zugewiesen.
 
 
 
 
 

 
 
sizeof(Name_eines_DatenTyps)
 
 
Das Ergebnis von sizeof ist eine Ganzzahl, welche den benötigten Speicherplatz für einen Datentyp im vorliegenden Rechner angibt. So ergibt beispielsweise sizeof(unsigned) den Wert 2, oder sizeof(double) den Wert 8.
 
 
 
 
 

 
 
return rückgabewert
return(rückgabewert)
 
 
Gelangt die Befehsausführung zu einem return-Befehl, so wird die Funktion beendet. Der Rückgabewert muss nur dann angegeben werden, wenn die abzubrechende Funktion für Rückgaben vorbereitet ist. Die runden Klammern sind bei dem Schlüsselwort return optional. Sie erinnern an den Aufbau einer Funktion der bei return jedoch nicht vorliegt.
 
 
 
 
 

 
 
break
 
 
Verwendung in Schleifenkonstrukten. Gelangt die Befehlsausführung innerhalb einer Schleife zu einem break-Befehl, so wird die Schleife abgebrochen.
 
 
 
 
 

 
 
continue
 
 
Verwendung in Schleifenkonstrukten. Gelangt die Befehlsausführung innerhalb einer Schleife zu einem continue-Befehl, so wird zum Anfang der Schleife gesprungen, ohne dass nach continue folgende Befehlszeilen ausgewertet werden.
 
 
 
 
 

 
 
_AH, _AL, _AX, _BX, _CX, _DX, _FLAGS
 
 
Über die Register-Pseudovariablen ist es unmittelbar aus einem C-Programm heraus möglich und ohne die Benutzung von Inlineassembler, auf die Benutzerregister der 80x86 CPU zuzugreifen. Beispielsweise wird durch ..
                                     char varnam
                                     varnam = _AL
                                     _AH = varnam

.. der momentane Wert des CPU-Registers AL in die C-Variable varnam übertragen um dann von varnam aus in das _AH-Register kopiert zu werden. Die verfügbaren Register-Pseudovariablen lauten ..
_AH, _AL, _AX, _BH, _BL, _BX, _CH, _CL, _CX, _DH, _DL, _DX, _FLAGS
_BP, _DI, _SI, _SP
 
 

 
 
 
 
www..de