<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[BIOS-Adressen ansprechen]]></title><description><![CDATA[<p><a href="http://www.dbforums.com/delphi-c-etc/971354-here-bios-addresses-fro-creating-os-etc.html" rel="nofollow">Hier</a> stehen diverse Adressen aus dem BIOS, zum Beispiel:</p>
<p>0040:00CE 2 Bytes<br />
Days since 1980</p>
<p>Wie kann ich darauf per C++-Programm zugreifen? Ich hab's so probiert:</p>
<pre><code class="language-cpp">short *address = reinterpret_cast&lt;short *&gt;(0x004000CE);
</code></pre>
<p>Allerdings weiß ich erstens nicht, ob das richtig ist. Könnte das bitte jemand bestätigen oder dementieren? Und zweitens gibt's ein Problem, wenn ich versuche, das ganze mit einem DOS-Compiler (z.B. Turbo C++ 3.0) zu erstellen:</p>
<pre><code class="language-cpp">short *address = (short *)0x004000CE;
</code></pre>
<p>Er sagt dann: &quot;Cannot cast from 'long' to 'short *'&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/278345/bios-adressen-ansprechen</link><generator>RSS for Node</generator><lastBuildDate>Tue, 25 Aug 2026 07:24:34 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/278345.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 05 Dec 2010 00:46:47 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to BIOS-Adressen ansprechen on Sun, 05 Dec 2010 00:46:47 GMT]]></title><description><![CDATA[<p><a href="http://www.dbforums.com/delphi-c-etc/971354-here-bios-addresses-fro-creating-os-etc.html" rel="nofollow">Hier</a> stehen diverse Adressen aus dem BIOS, zum Beispiel:</p>
<p>0040:00CE 2 Bytes<br />
Days since 1980</p>
<p>Wie kann ich darauf per C++-Programm zugreifen? Ich hab's so probiert:</p>
<pre><code class="language-cpp">short *address = reinterpret_cast&lt;short *&gt;(0x004000CE);
</code></pre>
<p>Allerdings weiß ich erstens nicht, ob das richtig ist. Könnte das bitte jemand bestätigen oder dementieren? Und zweitens gibt's ein Problem, wenn ich versuche, das ganze mit einem DOS-Compiler (z.B. Turbo C++ 3.0) zu erstellen:</p>
<pre><code class="language-cpp">short *address = (short *)0x004000CE;
</code></pre>
<p>Er sagt dann: &quot;Cannot cast from 'long' to 'short *'&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1989899</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1989899</guid><dc:creator><![CDATA[Hawaiica]]></dc:creator><pubDate>Sun, 05 Dec 2010 00:46:47 GMT</pubDate></item><item><title><![CDATA[Reply to BIOS-Adressen ansprechen on Sun, 05 Dec 2010 01:35:05 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">short *address = reinterpret_cast&lt;short *&gt;(0x004000CE);
</code></pre>
<p>ist prinzipiell korrekt, ist aber nur brauchbar, wenn man gerade selbst ein Betriebssystem schreibt, da unter Windows/Linux/[anderes Betriebssystem] Programme einen virtuellen Speicher zugeordnet bekommen.<br />
Liegt die Adresse 0x004000CE in einem Bereich dieses Speichers, auf den nicht zugegriffen werden darf, so stürzt das Programm einfach ab.</p>
<p>Hawaiica schrieb:</p>
<blockquote>
<p>Er sagt dann: &quot;Cannot cast from 'long' to 'short *'&quot;.</p>
</blockquote>
<p>Das liegt daran, dass DOS ein 16 Bit Betriebssystem ist, also Zeiger dort genau 16 Bit breit sind.<br />
Du kannst folglich keine 32 Bit Zahl (long) in einen 16 Bit Zeiger (short <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title="*)"
      alt="😉"
    /> konvertieren.</p>
<p>Im Realmode stellt 0x0040 die Segmentadresse und 0x00CE das Offset dar.<br />
der Zeiger bekommt also eig nur den Wert 0x00CE, während 0x0040 in einem der Segmentregister landet (bzw. einem zweiten Allzweck-Register).<br />
Das Problem hier ist, dass man das einem C++-Compiler nicht klar machen kann.</p>
<p>Also entweder du schreibst das in Assembler oder du benutzt den Inline-Assembler deines Compilers. Eine andere Möglichkeit sehe ich gerade nicht.</p>
<p>MfG DrakoXP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1989917</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1989917</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Sun, 05 Dec 2010 01:35:05 GMT</pubDate></item><item><title><![CDATA[Reply to BIOS-Adressen ansprechen on Sun, 05 Dec 2010 15:59:36 GMT]]></title><description><![CDATA[<p>Vielen Dank erst einmal für deine Hilfe.</p>
<p>DrakoXP schrieb:</p>
<blockquote>
<p>Liegt die Adresse 0x004000CE in einem Bereich dieses Speichers, auf den nicht zugegriffen werden darf, so stürzt das Programm einfach ab.</p>
</blockquote>
<p>Also, in meinem Fall soll dieses Programm ausschließlich in DOS laufen. Es geht darum, das Blinken von Text auszuschalten und stattdessen helle Hintergrundfarben zu aktivieren. <a href="http://www.delorie.com/djgpp/doc/libc/libc_490.html" rel="nofollow">Hier</a> steht, dass der Wert dieses Status das fünfte Bit von Adresse 0040h:0065h ist. Da es nun a) keine Funktion gibt, um den Wert abzufragen, sondern nur eine, um ihn zu setzen und ich das ganze bei Beendigung meines Programms auch gern wieder zurücksetzen möchte, und b) diese Funktion nur im DJGPP existiert, aber nicht unbedingt in Bibliotheken von anderen Compilern, will ich eben direkt mit der Adresse arbeiten.</p>
<p>DrakoXP schrieb:</p>
<blockquote>
<p>Im Realmode stellt 0x0040 die Segmentadresse und 0x00CE das Offset dar.<br />
der Zeiger bekommt also eig nur den Wert 0x00CE, während 0x0040 in einem der Segmentregister landet (bzw. einem zweiten Allzweck-Register).<br />
Das Problem hier ist, dass man das einem C++-Compiler nicht klar machen kann.</p>
<p>Also entweder du schreibst das in Assembler oder du benutzt den Inline-Assembler deines Compilers. Eine andere Möglichkeit sehe ich gerade nicht.</p>
</blockquote>
<p>Gibt es irgendwo eine Beschreibung, wie man das mit dem Segmentregister realisiert? (Per Inline-Assembler in C++, denn reines Assembler werde ich wohl nicht nehmen, da ja der Rest des Programms ganz normal in C++ erstellt werden kann.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1990117</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1990117</guid><dc:creator><![CDATA[Hawaiica]]></dc:creator><pubDate>Sun, 05 Dec 2010 15:59:36 GMT</pubDate></item><item><title><![CDATA[Reply to BIOS-Adressen ansprechen on Sun, 05 Dec 2010 17:25:14 GMT]]></title><description><![CDATA[<p>Schau mal im LowLevel-Wiki, da findest du bestimmt was du brauchst:</p>
<p><a href="http://www.lowlevel.eu/wiki/Textausgabe" rel="nofollow">http://www.lowlevel.eu/wiki/Textausgabe</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1990139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1990139</guid><dc:creator><![CDATA[bmario]]></dc:creator><pubDate>Sun, 05 Dec 2010 17:25:14 GMT</pubDate></item><item><title><![CDATA[Reply to BIOS-Adressen ansprechen on Sun, 05 Dec 2010 21:12:05 GMT]]></title><description><![CDATA[<p>Ich will nicht wissen, wie man mit Assembler Text ausgibt oder den Cursor oder die Farbe manipuliert, ich will nur ganz allgemein wissen, wie ich eine feste Adresse wie 0040h:0065h mit einem 16 Bit-C++-Compiler ansprechen kann. (Das Problem, dass das vier Byte sind und ein Zeiger in 16 Bit nur zwei Byte hat, wird in deinem Link zum Beispiel gar nicht behandelt.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1990237</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1990237</guid><dc:creator><![CDATA[Hawaiica]]></dc:creator><pubDate>Sun, 05 Dec 2010 21:12:05 GMT</pubDate></item><item><title><![CDATA[Reply to BIOS-Adressen ansprechen on Mon, 06 Dec 2010 08:57:48 GMT]]></title><description><![CDATA[<p>Um mit 16-Bit mehr als 64 kByte zu adressieren wurde das Segment:Offset Gedöns eingeführt. Die Berechnung der richtigen Adresse lautet <strong>Segment*16+Offset</strong>.<br />
Mit 16-Bit Segment und 16_Bit Offset kannst du damit 1024 KByte = 1 MByte adressieren. Der Pointer belegt aber 32-Bit.</p>
<p>Es gibt beim 8086 Prozessor verschiedene Segment-Register, die vor so einem Speicherzugriff gesetzt werden müssen. Das macht das ganze etwas aufwändiger und langsamer.<br />
Darum gibt es verschiedene Speichermodelle für die DOS-Programme.<br />
(Aus der Erinnerung)<br />
Alle Segmentregister sind gleich und fest:<br />
16-BitPointer<br />
Für Programm und Daten hast du zusammen max. 64 kByte</p>
<p>Die Segmentregister sind verschieden und fest:<br />
16-BitPointer<br />
Für Programm und Daten hast du je max. 64 kByte</p>
<p>Die Segmentregister sind verschieden und Variabel:<br />
32-BitPointer in Segment:Offset Darstellung<br />
Für Programm und Daten hast du je mehr als 64 kByte aber max. 1 MByte</p>
<p>Es gibt auch Mischformen (viel Daten,wenig Code oder wenig Daten/viel Code)</p>
<p>Um an die BIOS-Variablen zu kommen brauchst du einen 32-Bit-Pointer, da die Variable in einem anderen Segment liegt. Der heißt dann <strong>far-pointer</strong> und ist immer 32-Bit.</p>
<p>Anmerkung<br />
Die reale Adresse von 0040h:0065h und 0000:0465h ist die selbe.<br />
Aber die Pointer sind Unterschiedlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1990296</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1990296</guid><dc:creator><![CDATA[DirkB]]></dc:creator><pubDate>Mon, 06 Dec 2010 08:57:48 GMT</pubDate></item></channel></rss>