Turbo C: seg, ofs von Variable

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Antworten
markusk
Norton Commander
Beiträge: 132
Registriert: Fr 19. Apr 2013, 11:12

Turbo C: seg, ofs von Variable

Beitrag von markusk »

Hallo!

Gibt's in Turbo C Funktionen mit denen man die Segment- und Offsetadresse einer Variablen ermitteln kann?
In Turbo Pascal gibt es dafür die Funktion seg (variable) bzw. ofs (variable)

Müsste nämlich an eine Video-Interrupt Funktion die Segment- bzw. Offsetadresse eines Arrays im Registerpaar ES:BP übergeben (Segment in ES, Offset in BP).

lg, Markus
benjamin92
HELP.COM-Benutzer
Beiträge: 35
Registriert: Di 9. Aug 2016, 16:29

Re: Turbo C: seg, ofs von Variable

Beitrag von benjamin92 »

Also ich habe hier 2 Bücher über Turbo C 2.0, da steht über Adress-Berechung:
Segment-Register * 16 + Offset

Muss aber sagen, ich werde da selber nicht so wirklich schlau daraus :-(
markusk
Norton Commander
Beiträge: 132
Registriert: Fr 19. Apr 2013, 11:12

Re: Turbo C: seg, ofs von Variable

Beitrag von markusk »

Ich bräuchte den umgekehrten Weg, mit Segmentadresse * 16 + Offsetadresse kriegt man die effektive Adresse im Speicher, also wo die Variable im Speicher dann wirklich liegt.

In meinem Fall hab ich jedoch eine Variable, z.B.

int zahl;

Was ich hier nun bräuchte wäre die Segment- bzw. Offsetadresse jener Adresse an der diese Variable im Speicher liegt.
Also sowas wie seg (zahl) bzw. ofs (zahl) wie es wie bereits erwähnt in Turbo Pascal möglich ist.

Mein konkretes Problem: Ich hab ein Array

int buffer [4096];

Und muß die Segment- bzw. Offsetadresse von buffer einer Interrupt-Funktion in ES:BP übergeben.

lg, Markus
elianda
DOS-Übermensch
Beiträge: 1150
Registriert: Mi 31. Jan 2007, 19:04
Wohnort: Halle
Kontaktdaten:

Re: Turbo C: seg, ofs von Variable

Beitrag von elianda »

Kannst Du nicht im inline Assembler einfach
LES BP,buffer
ausfuehren?
Diverse Retro-Computer vorhanden.
idspispopd
Norton Commander
Beiträge: 108
Registriert: Fr 8. Mai 2015, 22:28
Wohnort: Hamburg

Re: Turbo C: seg, ofs von Variable

Beitrag von idspispopd »

Also &buffer liefert die Adresse des Arrays. Das gilt ganz allgemein für C, nicht nur für Turbo C. Jetzt kommt es vermutlich auf das gewählte Speichermodell an, wenn Du eines mit nur 64k Daten hast wird vermutlich nur der 16-bit-offset im Datensegment (near pointer) zurückgegeben (dann nimmst Du einfach DS für das Segment). Ansonsten ist das ein 32-bit-Wert, damit solltest Du weiterkommen.

In DOS.H sind hierfür die Makros FP_SEG und FP_OFF definiert, denen musst Du einen Pointer geben (also FP_SEG(&buffer) ) um Segment oder Offset zu bekommen. Das soll mit allen Speichermodellen funktionieren.
markusk
Norton Commander
Beiträge: 132
Registriert: Fr 19. Apr 2013, 11:12

Re: Turbo C: seg, ofs von Variable

Beitrag von markusk »

Hallo!

Nachfolgend mal mein Sourcecode. Das Ergebnis ist nicht das gewünschte, der Zeichensatz wird mit den falschen Bytes befüllt, das merkt man sofort am Bildschirm. Korrekterweise sollte keine Änderung der Zeichen erfolgen (ich wollte zunächst mal nur eine exakte Kopie des ROM-Fonts installieren).

Wo liegt hier der Fehler? Als Speichermodell ist Small eingestellt, aber der Fehler tritt auch bei den anderen Speichermodellen auf.

Code: Alles auswählen

#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <mem.h>
#include <alloc.h>

typedef unsigned char BYTE;
typedef unsigned int WORD;

int main () {
   int i;
   struct REGPACK cpu;
   BYTE far *font;
   BYTE far *fontPtr;
   
   font=farmalloc(4096); /* Platz reservieren für Font (256 Zeichen * 16 wegen der Zeichenhöhe von 16) */
   
   /* Mit der folgenden Interrupt-Funktion kann man die Adresse eines ROM-Fonts in Erfahrung bringen */
   /* Diese Daten kann man dann als "Rohmaterial" für eigene Fonts benutzen die man in einem Array ablegt */

   cpu.r_ax=0x1130;
   cpu.r_bx=0x0600;
   intr(0x10,&cpu);
   fontPtr=MK_FP(cpu.r_es,cpu.r_bp); /* Funktion liefert in ES:BP einen Zeiger auf den Font im ROM zurück */

   /* Font vom ROM in reservierten Puffer im RAM umkopieren */
   
   for (i=0 ; i < 4096 ; i++) {
      font[i]=fontPtr[i];
   }

   /* Mit der nachfolgenden Video Interrupt-Funktion kann man einen selbstdefinierten Zeichensatz */
   /* installieren. Die Quelle für das Aussehen der Zeichen soll hier der zuvor reservierte RAM-Puffer sein */
   /* Das Aussehen der Zeichen wird hier nicht verändert, es dürfte also keine Änderung des Zeichensatzes am Bildschirm */
   /* erfolgen wenn die Funktion korrekt ausgeführt wurde. */
   
   cpu.r_ax=0x1110; 
   cpu.r_bx=0x1000; /* BH=16 (Zeichenhöhe), BL=0 (Speicherblock)
   cpu.r_cx=256; /* Anzahl der zu installierenden Zeichen */
   cpu.r_dx=0; /* Ascii-Code des ersten Zeichens */
   cpu.r_es=FP_SEG(font); /* Segmentadresse des RAM-Fontbuffers */
   cpu.r_bp=FP_OFF(font); /* Offsetadresses des RAM-Fontbuffers */

   intr (0x10,&cpu);

   farfree(font);
   return 0;
}
lg, Markus
Antworten