Autor Thema: outportb in C  (Gelesen 18175 mal)

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« am: 11. January 2009, 17:46 »
Hallöchen,

ich bin gerade dabei mir eine C-Funktion zu schreiben, mit der man einen Byte großen Wert an einen Port schicken lassen können soll. Na ja, aber ich bin ja noch nicht so wirklich gut in C und in AT&T-ASM auch nicht wirklich. So, ich verwende gcc und der kennt ja leider nur die AT&T-syntax (bzw. dessen Assembler). Also so sieht das Ganze bei mir zurzeit aus:

void outportb(unsigned short port, unsigned char val)
{
asm("out val,port"); //tjo und das ist ja falsch
}

Irgendwie raffe ich die Erklärung des gcc inline Assemblers nicht. Man kann ja leider nicht direkt die Variablennamen val und port verwenden. Von daher weiß ich jetzt nicht weiter. Evtl. könnt ihr, die ihr schon lange mit C und dem ganzen Quatsch rumhantiert, mir helfen. Ich wäre euch dankbar.

bitmaster
In the Future everyone will need OS-64!!!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 11. January 2009, 18:49 »
Zitat
Irgendwie raffe ich die Erklärung des gcc inline Assemblers nicht.
Du meinst aber nicht diesen Artikel, oder?
Ich empfinde den Artikel als gut gelungen.

Trozdem hier mal der code den ich verwende.
static inline void outb( t_port port, uint8_t value )
{
    asm volatile ("out %1, %0" : : "Nd" (port), "a" (value) );
}

Edit:
Ich werde mir grad unsicher ob das wirklich optimal ist(nicht das gcc da für %1 ax oder eax nimmt).
Um sicher zu gehen solltest du besser 'outb' benutzen.
« Letzte Änderung: 11. January 2009, 18:57 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #2 am: 11. January 2009, 20:34 »
Ah cool, danke für den Link und die Lösung.

Noch was, mein gcc übersetzt folgendes nicht (ich habs mit objdump net gefunden):

tmp | 0x20
Wobei tmp eine unsigned char Variable ist. Also er sollte das machen was in asm so aussehen würde:

or [tmp],20h
thx

ARG ich trottel, es muss ja so lauten:

tmp = tmp | 0x20
^^
« Letzte Änderung: 11. January 2009, 20:38 von bitmaster »
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 11. January 2009, 21:02 »
Genau. Oder abkürzend tmp |= 0x20. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #4 am: 12. January 2009, 08:06 »
Genau. Oder abkürzend tmp |= 0x20. ;)
Jo danke, aber die Schreibweise gefällt mir nicht.  :-P

Werde aber bald wahrscheinlich wieder was zum Fragen haben. Also bis denn.  :-D
In the Future everyone will need OS-64!!!

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #5 am: 12. January 2009, 08:35 »
Was machst du denn momentan eigentlich in C, wenn man Fragen darf? :-)
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #6 am: 12. January 2009, 15:22 »
Was machst du denn momentan eigentlich in C, wenn man Fragen darf? :-)
http://www.os-64.de  :-D
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 12. January 2009, 18:39 »
Viele Details sind da aber noch nicht zu erkennen.

Vor allem nicht, wieso es plötzlich langsam sein darf. :P
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #8 am: 12. January 2009, 22:35 »
Viele Details sind da aber noch nicht zu erkennen.

Vor allem nicht, wieso es plötzlich langsam sein darf. :P
Was interessiert mich mein Geschwätz von gestern.

Ich bin Linux User, schreibe mein OS in C (und natürlich ein wenig ASM) und das ist gut so.  :wink:

EDIT: Äh ich habe mir mal so den disassemblierten Code meines Kernels mittels objdump angeschaut. Da macht C aber wirklich etwas langsam. Wie bringe ich gcc dazu aus einer Variablen keinen Speicherzugriff zu machen sondern ein schnelleres Register zu benutzen.

Also z.B. das hier:

unsigned short a;

a = blabla_memory[bla];
blabla_memory[bla+x] = a;

Da ist a nur ein Dummy. In ASM würde ich dafür ein Register benutzen. Aber gcc macht da einen Speicherzugriff raus (mittels Stack und ebp etc.). Da gibt es doch sicherlich Möglichkeiten dem zu sagen, dass die Variable nicht "ewig" gebraucht wird und er also ein Register benutzen kann, oder?

thx
« Letzte Änderung: 12. January 2009, 22:41 von bitmaster »
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 12. January 2009, 23:23 »
Optimierungen einschalten. ;)

gcc -O3 sollte selbst dich zufriedenstellen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #10 am: 15. January 2009, 19:32 »
So, nachdem ich jetzt 2 Tage dank einer Grippe nur im Bett gelegen habe, brauche ich jetzt mal wieder - wie angekündigt - Hilfe. Also folgendes:

Ich bin gerade dabei meine types.h zu schreiben. Also ich weiß, dass unter gcc

char8 Bit
short16 Bit
int32 Bit

groß sind. Aber was ist mit long? Ich dachte das wären dann 64 Bit. Aber mein Compiler sagt zu meinem Code:

unsigned long main()
{
return 0x100000000;
}

Zitat
cc1: warnings being treated as errors
ztest.c: In function ‘main’:
ztest.c:3: error: integer constant is too large for ‘long’ type
ztest.c:3: error: large integer implicitly truncated to unsigned type

Hmm... jetzt weiß ich nicht mehr weiter. Und was genau ist eigentlich long long? Damit funktioniert es nämlich auch nicht.

thx

bitmaster
In the Future everyone will need OS-64!!!

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #11 am: 15. January 2009, 20:09 »
Unter einem 32Bit System mit gcc ist long 32bit unter einem 64Bit System mit gcc 64Bit. Nur long long ist einheitlich 64Bit.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #12 am: 15. January 2009, 20:42 »
Unter einem 32Bit System mit gcc ist long 32bit unter einem 64Bit System mit gcc 64Bit. Nur long long ist einheitlich 64Bit.
thx

Aber wenn ich long long anstatt long schreibe, sagt gcc trotzdem "error: integer constant is too large for ‘long’ type".  :?

Und wie bringe ich gcc dazu meine Header-Dateien zu durchsuchen und nicht die des Standardverzeichnisses. Ich hab es mit --sysroot=<directory> versucht, aber irgendwie findet er die Dateien trotzdem nicht.
In the Future everyone will need OS-64!!!

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 15. January 2009, 20:52 »
0x100000000 braucht mindestens 33 Bit Platz. Deswegen meckert GCC. Die Zahl bekommt nicht durch den Rückgabetyp der Funktion den Typ long long, sondern durch ein Suffix: 0x100000000ULL (ULL = unsigned long long). Es gibt auch LL für signed long long. Außerdem UL und L für unsigned long/long.
Dieser Text wird unter jedem Beitrag angezeigt.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #14 am: 15. January 2009, 21:00 »
0x100000000 braucht mindestens 33 Bit Platz. Deswegen meckert GCC. Die Zahl bekommt nicht durch den Rückgabetyp der Funktion den Typ long long, sondern durch ein Suffix: 0x100000000ULL (ULL = unsigned long long). Es gibt auch LL für signed long long. Außerdem UL und L für unsigned long/long.
Danke, mit ULL funktioniert es. Aber wofür dann ein "Rückgabetyp der Funktion" wenn es damit sowieso nicht geht?  :-o

Ach ja: es stehen noch Fragen offen:  :-D
In the Future everyone will need OS-64!!!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 15. January 2009, 21:31 »
gcc Optionen:

-nostdinc     : um die standard Verzeichnisse zu ignorieren
-iquote <dir> : Include Verzeichnis nur für #include "foo.h"
-I <dir >     : include Verzeichnis für #include <foo.h> und #include "foo.h"
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #16 am: 15. January 2009, 21:50 »
gcc Optionen:

-nostdinc     : um die standard Verzeichnisse zu ignorieren
-iquote <dir> : Include Verzeichnis nur für #include "foo.h"
-I <dir >     : include Verzeichnis für #include <foo.h> und #include "foo.h"
Jou vielen dank, jetzt geht es. Sagt mal wie kommt man eigentlich an die ganzen Infos zu allen gcc Parametern ran. Ein gcc --help gibt mir nicht allzu viel aus.

thx

bitmaster
In the Future everyone will need OS-64!!!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 15. January 2009, 21:54 »
wenn du die gcc-doc installiert hast
man gccoder noch ausführlicher hier bzw.
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/
« Letzte Änderung: 15. January 2009, 21:58 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #18 am: 15. January 2009, 22:31 »
wenn du die gcc-doc installiert hast
man gccoder noch ausführlicher hier bzw.
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/
ah cool, vielen dank

Und schon wieder ein Problem:

Gcc sagt:

Zitat
video.c:74: error: conflicting types for ‘PrintC’
../include/video.h:12: error: previous declaration of ‘PrintC’ was here

Weiß jetzt nicht was ich falsch gemacht haben soll. Also ich habe eine kernel.c, eine video.c und eine video.h. In der kernel.c rufe ich die Funktionen Print und PrintC auf. In der video.c ist der code der Print und PrintC. Print ruft selbst aber auch PrintC auf (dürfte doch kein Problem sein, oder kommt der dann durcheinander?). Jo und in der video.h habe ich dann noch mal schön das da stehen:

#ifndef _VIDEO_H_
#define _VIDEO_H_

//print a message
void Print(char* msg);

//print a character
void PrintC(unsigned character);

#endif // ifndef _VIDEO_H_

ALso ich sehe da keinen Fehler.  :?

bitmaster
In the Future everyone will need OS-64!!!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 15. January 2009, 22:48 »
Damit man es genau sagen kann, müßtest du noch Zeile 74 in der video.c herzeigen. Anscheinend hast du die Funktion dort anders definiert als in der Headerdatei. Und das geht natürlich nicht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen