Fragen und Antworten zum C-Kurs

Software-Entwicklung, Compiler, Interpreter, ...
Paul
Beiträge: 146
Registriert: 17.09.2017, 22:27
Wohnort: Germanys west end

Re: Fragen und Antworten zum C-Kurs

Beitrag von Paul »

Ich habe eine Weile suchen müssen um die Z88 Doku zu finden.
Da habe ich mich wahrscheinlich blöd angestellt.
Anyway: https://github.com/z88dk/z88dk/wiki
Benutzeravatar
bbock
Beiträge: 247
Registriert: 08.02.2015, 15:31

Re: Fragen und Antworten zum C-Kurs

Beitrag von bbock »

Paul hat geschrieben: 03.09.2023, 08:44 ...
Gibt es eine Liste von sinnvollen Speicheradressen für die Joyce wie z.B. Systemvariablen aus denen man sinnvolles auslesen oder die man sinnvoll manipulieren kann so wie bei den ZX-Maschinen?
Die ZX-Computer von Sinclair haben ein BASIC im ROM, das gleichzeitig das Betriebssystem ist. Der PCW hat aber kein Betriebssystem im ROM; wenn man eines benötigt, dann wird es wird beim Einschalten von Diskette gebootet. Meist ist das CP/M Plus. Man kann aber auch Programme ohne Betriebssystem booten, wie z.B. LocoScript. Daher gibt es auch keine Systemvariablen wie bei den BASIC-Rechnern. Schon möglich, dass es ein paar interessante Speicheradressen gibt, z.B. für CP/M Plus, aber da fällt mir jetzt nichts ein...
Benutzeravatar
bbock
Beiträge: 247
Registriert: 08.02.2015, 15:31

Re: Fragen und Antworten zum C-Kurs

Beitrag von bbock »

Paul hat geschrieben: 03.09.2023, 09:11 Kann es sei das du dich vertippt hast Bernd?
bbock hat geschrieben: 18.08.2023, 10:10

Code: Alles auswählen

zcc +cpm -subtype=pcw80 -compiler=sccz80 -pragma-define:REGISTER_SP=0xF3FF -create-app testprg1.c -o testprg1.com
Die pragma-define-Option stellt sicher, dass der Stackpointer bei FFF0 beginnt. Damit bleibt der Speicherbereich ab F400 sicher vor Überschreibung durch den Stack.
Du wolltest wahrscheinlich schreiben das der Stackpointer bei F3FF nicht bei FFF0?
Richtig erkannt; ich habe den Fehler korrigiert. Danke für den Hinweis.
Benutzeravatar
bbock
Beiträge: 247
Registriert: 08.02.2015, 15:31

Re: Fragen und Antworten zum C-Kurs

Beitrag von bbock »

Paul hat geschrieben: 03.09.2023, 09:33 Und gleich noch eine Frage hinterher:
beim zweiten Beispiel hast die Variable ch global definiert.
Ich wollte sie natürlich gleich lokal definieren was der compiler nicht mag.
Um so größer war meine Verwunderung das der Compiler die unveränderte Zeile als globale Variable akzeptiert.
..,
Wenn du eine Variable lokal anlegst, also innerhalb einer Funktion, dann legt sie der Compiler auf dem Stack an (es sei denn, du deklarierst sie als static). Damit bekommt jeder Funktionsaufruf seine eigenen lokalen Variablen, wodurch z.B. Rekursion ermöglicht wird. Der Speicherplatz wird zur Laufzeit beim Funktionsaufruf durch Ändern des Stack Pointers (dem Z80-Register SP) reserviert und am Ende der Funktion wieder freigegeben (abermals durch Ändern des Stack Pointers). Man spricht auch von "automatischen Variablen". Sie haben naturgemäß keine festen Adressen, da sie vom Inhalt des Stack Pointers abhängen. Ergo macht die Zuordnung einer festen Speicheradresse keinen Sinn und der Compiler quittiert den Versuch mit einer Fehlermeldung.
Globale Variablen werden vom Compiler zur Compile-Zeit festen Speicheradressen zugeordnet (dasselbe gilt für static-Variablen). Während des Programmlaufs ändern diese sich nicht mehr. Hier macht es also Sinn, dem Compiler eine feste Adresse mit '@* vorzugeben. Diese verwendet er dann anstelle der Adresse, die er ohne '@'-Klausel automatisch ermittelt hätte.
Paul
Beiträge: 146
Registriert: 17.09.2017, 22:27
Wohnort: Germanys west end

Re: Fragen und Antworten zum C-Kurs

Beitrag von Paul »

Verstanden. Da hatte ich zuviel erwartet.
Dann ist das Beispiel mit der lokalen Variable *p und der lokalen Zuweisung also auch "ungünstig".
Die wäre dann ja global auch besser aufgehoben.
Vielen Dank für die Erklärung!
Keine Ahnung ob du da nicht etwas geplant hast: eine kleine Beispiel Assembler Funktion fände ich auch noch ganz nett.
Die Kapitel dazu habe ich gelesen.
Insbesondere eins mit mehreren Parametern über den Stack und eins mit Fastparameter über HL finde ich ganz interessant.
Paul
Beiträge: 146
Registriert: 17.09.2017, 22:27
Wohnort: Germanys west end

Re: Fragen und Antworten zum C-Kurs

Beitrag von Paul »

Mit static will der Compiler es aber auch nicht lokal :cry:
Egal. Global geht es ja.
Paul
Beiträge: 146
Registriert: 17.09.2017, 22:27
Wohnort: Germanys west end

Re: Fragen und Antworten zum C-Kurs

Beitrag von Paul »

Dann meine Frage zu malloc:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
  unsigned int i;	
  int n, result;
  char *buffer;
 
  printf("Wieviele Sterne? ");
  scanf("%u", &i);
 
  buffer = (char*) malloc(i + 1);  // ein Byte extra für das String-Ende-Zeichen
  if (buffer != NULL) {            // sonst haben wir keinen Speicher bekommen
    buffer[i] = '\0';              // String-Ende-Zeichen setzen

    while(i--) {
      buffer[i] = '*';             // String mit Sternchen füllen
    }

    printf("%s\n", buffer);
    free(buffer);                  // Wichtig! Speicher wieder freigeben

    result = EXIT_SUCCESS;
  }
  else {
    printf("Not enough memory to create %u stars\n", i);
    result = EXIT_FAILURE;
  }
  
  return result;
}
Ich habe es ja auf unsigned int umgebaut.
Bis 32767 funktioniert es wie erwartet, ab 32768 gibt es erst Leerzeilen aus bevor es mit Sternen anfängt (ich beschleunige den Emulator dann mit der ">>" Taste).
Wird die Zahl groß genug schlägt malloc fehl und es wird die Fehlermeldung ausgegeben (wie erwartet).
Woher kommen die Leerzeilen? Kann printf das nicht?
Benutzeravatar
bbock
Beiträge: 247
Registriert: 08.02.2015, 15:31

Re: Fragen und Antworten zum C-Kurs

Beitrag von bbock »

Da hat wohl die Implementierung der printf-Funktion ein Problem mit Strings, die länger als 32.767 Zeichen sind. Das ist wohl ein Bug in der library.
Wenn du den Code folgendermaßen änderst, dann geht's:

Code: Alles auswählen

...
  char *p;
 
  printf("Wieviele Sterne? ");
  scanf("%u", &i);
 
  buffer = (char*) malloc(i + 1);  // ein Byte extra für das String-Ende-Zeichen
  if (buffer != NULL) {            // sonst haben wir keinen Speicher bekommen
    buffer[i] = '\0';              // String-Ende-Zeichen setzen

    while(i--) {
      buffer[i] = '*';             // String mit Sternchen füllen
    }

//    printf("%s\n", buffer);
    p = buffer;
    while (*p != '\0') {
        putchar(*p++);
    }
    putchar('\n');

    free(buffer);                  // Wichtig! Speicher wieder freigeben
...
Paul
Beiträge: 146
Registriert: 17.09.2017, 22:27
Wohnort: Germanys west end

Re: Fragen und Antworten zum C-Kurs

Beitrag von Paul »

Sehr gut. Vielen Dank.
Dann war meine Vermutung ja mal richtig.
So lange strings machen aber auch nur selten Sinn.
Ziel meiner Übung waren ja nicht ganz viele Sterne sondern die Fehlermeldung zu bekommen das soviel nicht alloziert werden kann :ugeek:
Antworten