Forum: PC-Programmierung Wie weit kann man den Malloc-Speicher treiben 1x 5x beim 8086?


von Peter B. (funkheld)


Angehängte Dateien:

Lesenswert?

Hallo, guten Tag.

Ich habe jetzt 2 x Malloc mit 64000 Byte ,wenn ich es richtig gemacht 
habe.

Habe tcc -ml .... compiliert.

Es kommt keine Fehlermeldung und die Werte werden ausgegeben.
Ich kann trotzdem nicht beurteilen ob nicht Fehler verschlammt wurden.

Danke.
Gruss

---------------------
#include <stdio.h>
#include <stdlib.h>

int main(void) {
unsigned   char *p = malloc(64000 * sizeof(unsigned char));
unsigned   char *z = malloc(64000 * sizeof(unsigned char));

   if(p != NULL) {
      *p=99;             /* alternativ auch p[0] = 99  */
      *(p+63999) = 255;  /* alternativ auch p[63999] = 255 */
      *z=100;            /* alternativ auch p[0] = 100  */
      *(z+63999) = 101;  /* alternativ auch p[63999] = 101 */
      printf("Allokation erfolgreich ... \n");
   }
   else {
      printf("Kein virtueller RAM mehr verfuegbar ...\n");
      return EXIT_FAILURE;
   }
   printf("%d %d\n", p[0], p[63999]);
   /* Sie können die Werte auch so ausgeben lassen. */
   printf("%d %d\n", *p, *(p+63999));

   printf("%d %d\n", z[0], z[63999]);
   /* Sie können die Werte auch so ausgeben lassen. */
   printf("%d %d\n", *z, *(z+63999));
   return EXIT_SUCCESS;
}
--------------

: Bearbeitet durch User
von MaWin (Gast)


Lesenswert?

Im large Speichermodell bis der bis 4GB fassende 32 bit Speicher voll 
ist. Notfalls wird vom Betriebssystem geswappt.
Du kannst halt keinen Block mit 66000 bytes malloc'en.

von Peter B. (funkheld)


Lesenswert?

Danke für die info.

Gruss

von Malle (Gast)


Lesenswert?

Die Prüfung von z != NULL fehlt.
Außerdem ist per Sprachdefinition sizeof(unsigned char) = sizeof(signed 
char) = sizeof(char) = 1

Grüße

von Peter B. (funkheld)


Lesenswert?

Danke habe ich geändert.
Keine Speicherengpassmeldung.

Gruss

von Peter B. (funkheld)


Lesenswert?

Hallo, gute Tag.

Ich wollte jetzt den VGA-Inhalt (VGA 320x200 256 Color) nach Malloc 
copieren.

Und wenn sich das Sprite bewegt wollte ich das Loch im VGA mit den 
Inhalt von  Malloc wieder flicken.

Ich wollte es evtl in ASM machen .
Wo finde ich das bestimmte Segment von Malloc dafür.
Fängt dort der Speicher auch bitte bei Null an ?  zb 0xd000:0

Oder ein von beiden welches ist bitte günstiger und schneller :
*(p+63999) = 255; oder
p[63999] = 255;

Danke.
Gruss

: Bearbeitet durch User
von cppbert (Gast)


Lesenswert?

MaWin schrieb:
> Im large Speichermodell bis der bis 4GB fassende 32 bit Speicher
> voll
> ist. Notfalls wird vom Betriebssystem geswappt.
> Du kannst halt keinen Block mit 66000 bytes malloc'en.

Das läuft unter Dos, da wird nichts geswappt

von cppbert (Gast)


Lesenswert?

Peter B. schrieb:
> Ich wollte es evtl in ASM machen .
> Wo finde ich das bestimmte Segment von Malloc dafür.
> Fängt dort der Speicher auch bitte bei Null an ?  zb 0xd000:0

Das Ergebnis von malloc ist in deinem Fall das Segment

> Oder ein von beiden welches ist bitte günstiger und schneller :
> *(p+63999) = 255; oder
> p[63999] = 255;
>
> Danke.
> Gruss

Die Array Zuweisungen erzeugt identischen Code

von Fehlanzeige (Gast)


Lesenswert?

Auf einem 286er könnte man glatt 1 MB per malloc bekommen!
In einem Rutsch!

von Rolf M. (rmagnus)


Lesenswert?

MaWin schrieb:
> Im large Speichermodell bis der bis 4GB fassende 32 bit Speicher voll
> ist. Notfalls wird vom Betriebssystem geswappt.

DOS kennt kein Swapping. Und es kennt auch keine 4 GB RAM, außer 
vielleicht über extended oder expanded memory. Da kommt man aber mit 
einem simplen malloc nicht dran. Auch im Large-Modell kann ein Zeiger 
nicht mehr als 1 MB (plus 65520 Bytes, die HMA) adressieren.

: Bearbeitet durch User
von Frank K. (fchk)


Lesenswert?

Peter B. schrieb:
> Hallo, gute Tag.

AH, immer noch da.

> Wo finde ich das bestimmte Segment von Malloc dafür.

So, Grundlagen:

Physikalische Adresse: Segment*16+Offset.
Ein an einer 16 Byte Grenze liegender Block von 16 Bytes nennt man 
Paragraph.

Bei large und huge arbeitest Du mit FAR Pointern, d.h. Pointer mit 32 
Bit Größe und Segment:Offset.
Bei small arbeitest Du mit NEAR Pointern.

FAR und NEAR sollten als Macros irgendwo in einem Headerfile definiert 
sein.

mit p=MK_FP(seg,ofs) bastelst Du Dir einen FAR Pointer aus Segment und 
Offset.
seg=SEG(p); ofs=OFS(p); geben Dir Segment und Offset eines FAR Pointers.

Pointer, die Du von malloc bekommst, sollten an einer Paragraphengrenze 
starten. Dabei ist nicht garantiert, dass der Offset 0 ist. 
Normalisieren musst Du den Pointer selber, d.h. physikalische Adresse 
berechnen, durch 16 ergibt Segment, Rest ist Offset.

Das hättest Du jetzt auch in einem Buch nachlesen können.

> Oder ein von beiden welches ist bitte günstiger und schneller :
> *(p+63999) = 255; oder
> p[63999] = 255;

egal.

fchk

von cppbert (Gast)


Lesenswert?


von Peter B. (funkheld)


Lesenswert?

Hallo, danke für die Hilfe.

Gruss

von S. R. (svenska)


Lesenswert?

Fehlanzeige schrieb:
> Auf einem 286er könnte man glatt 1 MB per malloc bekommen!
> In einem Rutsch!

Auch falsch.

von Pandur S. (jetztnicht)


Lesenswert?

Der 8086 hatte noch keine MMU, noch keine pages, kein Swap..
Der hat 4 Segment register, CS, DS, ES, SS, und dazu gehoeren Pointer.
Also CS:IP, DS:DX, ES:EX, SS:SP. Jeder pointer kann 16 bit adressieren, 
das Segmentregister ist um 4 Verschoben. Die Adressen sind also 20Bit. 
Macht also 1MByte Adressraum.
Schade gab's kein DOS fuer den 386, der war naemlich viel besser, viel 
interessanter. Allerdings waeren viele damit ueberfordert gewesen.

: Bearbeitet durch User
von Achim (Gast)


Lesenswert?

Peter B. schrieb:
> Es kommt keine Fehlermeldung und die Werte werden ausgegeben.

Kommt die überhaupt?

Soweit ich weiß, wird der Speicher doch dann zur Laufzeit allokiert, was 
dann ggf. zu einem segfault führt, wenn nicht genügend 
(zusammenhängender) Speicher zur Verfügung steht.

Aber zur Compilezeit?

von S. R. (svenska)


Lesenswert?

Achim schrieb:
> Soweit ich weiß, wird der Speicher doch dann zur Laufzeit
> allokiert, was dann ggf. zu einem segfault führt,

Unter DOS gibt es keine Segfaults. Gibt die Hardware nicht her.

> wenn nicht genügend (zusammenhängender) Speicher zur Verfügung steht.

Dann gibt malloc() einfach NULL zurück.
Was in jedem Segment ein gültiger Wert ist...

von Rolf M. (rmagnus)


Lesenswert?

Joggel E. schrieb:
> Der hat 4 Segment register, CS, DS, ES, SS, und dazu gehoeren Pointer.
> Also CS:IP, DS:DX, ES:EX, SS:SP.

DX und EX sind keine Pointer-Register. Die Kombinationen sind DS:SI 
(source index) und ES:DI (destination index). Und dann gibt es noch den 
"base pointer" BP.

> Jeder pointer kann 16 bit adressieren, das Segmentregister ist um 4
> Verschoben. Die Adressen sind also 20Bit.
> Macht also 1MByte Adressraum.

+65520 Bytes. Da der 8086 aber nur 20 Adressleitungen hat, ist dort der 
untere Speicherbereich gespiegelt. Ab dem 286 konnte man aber 
tatsächlich den zusätzlichen Speicher ansprechen. Aus diesem Umstand 
stammt das berühmt-berüchtigte A20-Gate.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.