Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
lehrkraefte:blc:informatik:ffprg2-2018:ffprg2-2018 [2019/01/18 15:45] – [Hackme Code] Ivo Blöchligerlehrkraefte:blc:informatik:ffprg2-2018:ffprg2-2018 [2019/01/25 14:34] (current) – [Assembler und Hacking (Stackoverflow)] Ivo Blöchliger
Line 1: Line 1:
 +====== https://fginfo.ksbg.ch ======
  
 +====== Freifach Programmieren ======
 +In diesem Kurs werden die Grundlagen von C++ vermittelt, mit Fokus auf die Anwendung mit der
 +Arduino-IDE. Damit werden dann Elektronik-Experimente mit Arduino und/oder ESP32 programmiert.
 +
 +Ziel ist es, bis vor den Herbstferien so weit mit C++ vertraut zu sein, damit erste Elektronik-Experimente angegangen werden können.
 +
 +Sammlung von Tutorials und Dokumentation:
 +  * Tutorials: http://ewla.de/dozent/cpp/cpp7.pdf
 +  * Dokumentation: http://www.cplusplus.com/reference/
 +
 +====== Hacking ======
 +===== XSS: Cross Site Scripting =====
 +https://glf.tech-lab.ch/techlab/hackme/index.php
 +
 +===== Assembler und Hacking (Stackoverflow) =====
 +Ein aktueller Hack vom letzten Chaos Computer Congress: https://www.jaybosamiya.com/blog/2019/01/02/krautflare/
 +
 +
 +  * https://fginfo.ksbg.ch/~ivo/assembler-simulator/
 +
 +===== 7-Segment-Anzeige-Demo =====
 +Die 3 Segmente sind an den Adressen 253, 254 und 255, die Bits beginnen oben, dann im Urzeigersinn, am Schluss die Mitte.
 +<code asm>
 +start:
 +MOV [253], 1b
 +MOV [253], 10b
 +MOV [253], 100b
 +MOV [253], 1000b
 +MOV [253], 10000b
 +MOV [253], 100000b
 +MOV [253], 1000000b
 +
 +JMP start
 +</code>
 +
 +Mit etwas mehr Assembler Voodoo:
 +<code asm>
 +start:
 + MOV A,1
 +loopA:
 + MOV B, 253
 +loopB:
 + MOV [B], A
 + INC B
 + JNC loopB
 +
 + SHL A,1
 + JNC loopA
 +
 + JMP start
 +</code>
 +
 +Der L0L-Dreizeiler
 +<code asm>
 +MOV [253], 0111000b
 +MOV [254], 0111111b
 +MOV [255], 0111000b
 +</code>
 +
 +
 +Manipulierte Rücksprungadresse
 +
 +<code asm>
 + mov A, 'A'   ; Schreibt 65 (ASCII A) ins Register A
 +start:
 + inc A          ; Erhöht den Inhalt vom Register A um 1
 + mov [232], A   ;Schreibt den Wert 65 'A' in die Zelle 232
 + call bla         ;Unterprogramm aufrufen (Adr. auf Stack)
 +ruecksprung:
 + hlt ;Halt
 +
 +
 +bla:
 + mov [253], A   ;Alle 7 Bits für 7-Segment-Anzeige
 + mov [SP+1], start    ; Rücksprungadresse überschreiben
 + ret                   ;Rücksprung auf nach call
 +</code>
 +
 +
 +Ausgabe des LOL-Codes:
 +<code asm>
 +
 +lol:
 +MOV [253], 0111000b
 +MOV [254], 0111111b
 +MOV [255], 0111000b
 +
 +fertig:
 + mov A, fertig
 + dec A
 + mov B, 252
 +loop:
 + mov C, [A]
 + mov [B], C
 + dec B
 + dec A
 + JNC loop
 + hlt
 +
 +</code>
 +===== Hackme Code =====
 +Studieren Sie folgenden Code:
 +<code asm>
 +; Dieses Programm gibt den String rechtsbündig ab 
 +; Adresse 250 aus.
 +;
 + JMP start
 + DB "hello world"
 +;
 +; Register
 +; A Ausgabe-Adresse
 +; B Position in DB
 +; C temporär
 +
 +start: MOV A,250 ; Adresse Ausgabe (letzter Buchstabe)
 + MOV B, start    ; Adresse+1 vom letzten Buchstaben
 + DEC B ; B vermindern
 + CALL ausgabe
 + HLT
 +ausgabe:
 + MOV C,[B] ; Buchstabe in C
 + MOV [A],C ; Ausgabe
 + DEC A ; A vermindern
 + DEC B ; B vermindern
 + CMP B,1 ; ist B am Anfang angekommen?
 + JNE ausgabe ; sonst wiederholen
 + RET
 +</code>
 +
 +Schaffen Sie es, indem Sie nur die DB-Zeile anpassen (das wäre so quasi der User-Input), dass <nowiki>LOL</nowiki> auf der 7-Segment Anzeige erscheint? 
 +
 +<hidden Lösungsvorschlag>
 +Mit Rücksprung direkt in die DB-Konstante (Adresse 0x02)
 +<code asm>
 +DB "ý8þ?ÿ8+       Hello World!"
 +</code>
 +Oder mit Rücksprung in die kopierten Daten an der Adresse 0xdc:
 +<code asm>
 +DB "ý8þ?ÿ8+Ü       Hello World!"
 +</code>
 +
 +</hidden>
 +
 +
 +===== Busy Beaver =====
 +<code asm>
 +start:
 + MOV B, 255
 +
 +humpfdidumpf:
 + MOV A, [B]
 + INC A
 + MOV [B], A
 + JNC humpfdidumpf
 +while:
 + DEC B
 + CMP B, ende
 + JE ende
 + MOV A, [B]
 + INC A
 + MOV [B], A
 + JC while
 + JMP start
 +ende:
 + HLT
 +</code>
 +
 +===== Roborobo-Fernbedienung / Ivobot =====
 +* RoboRobo-Fernbedienung: {{ :ffprog:ffprogjava2016:roborobo.zip |roborobo Arduino Library}} (Sketch -> Add Library -> Add .zip)
 +* IvoBot:
 +  * {{ :lehrkraefte:blc:robotics:ivobot.zip |Source-Code zum Ivobot}}
 +  * [[https://fginfo.ksbg.ch/~ivo/ivobot/|Dokumentation]]
 +  * Seite der BU2 2017 [[lehrkraefte:blc:robotics:ablauf|Beschreibung und Source-Code zum Ivobot]]
 +
 +
 +===== Lektion 10 (Freitag 9. November 2018) =====
 +=== Potentiometer auslesen ===
 +Ein Potentiometer hat normalerweise 3 Anschlüsse. Der Widerstand zwischen 1. und 3. Anschluss ist konstant (z.B. 10k$\Omega$). Der Widerstand zwischen 1. und 2. Anschluss kann stufenlos geregelt werden, zwischen 0 und dem Gesamtwiderstand.
 +
 +Typischerweise wird zwischen 1. und 3. Anschluss 5V angelegt und die Spannung am 2. Anschluss gemessen. Diese variiert dann stufenlos zwischen 0V und 5V, vorausgesetzt, es kann (praktisch) kein Strom über Anschluss 2 abfliessen.
 +
 +Der 2. Anschluss wird am Arduino an einen der "Analog-Ports" angeschlossen, A0 bis A5. Die Spannung kann mit 10 Bit Auflösung ausgelesen werden mit
 +<code c++>
 +  int wert = analogRead(A0);
 +</code>
 +Man erhält einen Wert zwischen 0 (0V) und 1023 (5V). 
 +
 +=== Hardware PWM ===
 +Der Arduino kann Hardware ein PWM-Signal erzeugen, und zwar auf den Pins 3, 5, 6, 9, 10, 11.
 +
 +Mit einer Auflösung von 8 Bit kann das Signal wie folgt gesteuert werden:
 +<code c++>
 +  // im setup():
 +  pinMode(3, OUTPUT);
 +  
 +  // sonst wo:
 +  analogWrite(3, 127); // Halbe Kraft voraus... 0 heisst augeschaltet, 255 eingeschaltet
 +</code>
 +
 +=== Mögliche Aufgaben ===
 +
 +  * Steuerung der Helligkeit einer LED
 +  * Steuerung der Motorengeschwindigkeit.
 +===== Lektion 7 (Freitag 26. Oktober 2018) =====
 +Debugging. Im Setup
 +  Serial.begin(115200)
 +Im Code:
 +  Serial.print(i);
 +  Serial.print(" ist ");
 +  Serial.println(j);
 +Die Ausgabe unter Tools -> Serial Monitor (Ctrl-Shift-M) anschauen.
 +
 +===== Lektion 6 (Freitag 28. September 2018) =====
 +LEDs dimmen mit PWD (Pulsweitenmodulation).
 +
 +Idee. Ganz schnell ein- und ausschalten. Zeit, während der die LED eingeschaltet ist variieren.
 +
 +===== Lektion 5 (Freitag 14. September 2018) =====
 +Installation der Arduino-IDE:
 +  * https://www.arduino.cc/en/Main/Software (Windows-Installer auf den eigenen Geräten, zip-Datei auf den Schulcomputern)
 +  * Auf den Schulcomputern einen Ordner auf C:\ anlegen und die IDE darin entpacken.
 +
 +
 +
 +
 +<code cpp>
 +
 +int ports[] = {12,11,10};
 +int num = sizeof(ports)/sizeof(int);  // Anzahl Elemente
 +
 +void setup() {
 +  // put your setup code here, to run once:
 +  for (int i=0; i<num; i++) {
 +    pinMode(ports[i], OUTPUT);
 +  }
 +}
 +
 +void loop() {
 +  // put your main code here, to run repeatedly:
 +  for (int i=0; i<num; i++) {
 +    digitalWrite(ports[i], HIGH);
 +    delay(100);  // 100ms warten
 +    digitalWrite(ports[i], LOW);
 +  }
 +  delay(500);
 +}
 +</code>
 +
 +===== Lektion 4 (Freitag 7. September 2018) =====
 +==== Arrays ====
 +<code cpp>
 +  // Nur für kleine Arrays!
 +  int zahlen[10];  // Variablenname ist Plural!
 +  zahlen[0]=2;     // Erstes Element Index 0
 +  zahlen[9]=42;    // Letztes Element hat Index Länge -1
 +  
 +  //  Für grosse Arrays:
 +  int grenze = 10000000;            // Bis **ohne** diese Grenze!
 +  bool* prim = new bool[grenze];    // kein new ohne delete!
 +
 +  delete[] prim;    // Speicher wieder freigeben  
 +</code>
 +
 +==== Sieb von Erathostenes ====
 +<hidden Lösungsvorschlag>
 +<code cpp>
 +#include <iostream>
 +
 +using namespace std;
 +
 +int main()
 +{
 +    int grenze = 100000000;
 +    bool *prim = new bool[grenze];
 +    cout << "Alloc finished" << endl;
 +    // Initialisierung
 +    for (int i=0; i<grenze; i++) {
 +        prim[i] = i>1;
 +    }
 +    cout << "Init done " << endl;
 +    int akt = 0;   // Zahl zum Abstreichen
 +    while (akt*akt<=grenze) {  // Abstreichen bis zur Wurzel
 +        while (!prim[++akt]);   // Nächste Primzahl ermitteln, ! heisst "nicht"
 +        for (int p=akt*akt; p<grenze; p+=akt) {   // Zahlen abstreichen
 +            prim[p] = false;
 +        }
 +    }
 +    // Ausgabe der Liste
 +    for (int i=0; i<grenze; i++) {
 +        if (prim[i]) {
 +            cout << i << endl;
 +        }
 +    }
 +    // Speicher wieder freigeben
 +    delete[] prim;
 +    return 0;
 +}
 +
 +</code>
 +</hidden>
 +
 +
 +===== Lektion 3 (Freitag 31. August 2018) =====
 +==== Wahrheitswerte ''true'' und ''false'': Datentyp ''bool'' ====
 +Das Ergebnis eines Vergleichs (z.B. mit ==, !=, <, >, etc. ist ein Wahrheitswert ''true'' oder ''false''. Diese Werte können in einer Variable mit Typ **bool** gespeichert werden.
 +<code cpp>
 +bool gleich;
 +gleich = (42==6*7);
 +if (gleich) {   // Gleicher effekt wie gleich==true
 +   cout << "gleich ist wahr: " << gleich << endl;
 +} else {
 +   cout << "gleich ist falsch: " << gleich << endl;
 +}
 +</code>
 +
 +Hinweis: Werden andere Typen als bool interpretiert, ist alles wahr, was nicht Null ist. Wird ein bool als Zahl interpretiert, kommt 0 (für false) oder 1 (für true) heraus.
 +
 +==== Primzahlen ausgeben ====
 +Schreiben Sie ein Programm, das alle Primzahlen bis zu einer gegebenen Grenze ausgibt.
 +
 +<hidden Lösungsvorschläge>
 +<code cpp>
 +#include <iostream>
 +#include "math.h"
 +
 +using namespace std;
 +
 +int main()
 +{
 +    int grenze = 10000000;
 +    int anzahl = 1;
 +    int maxprimes = 1000;
 +    int primes[1000];
 +    primes[1] = 3;
 +
 +    for (int k=3; k<=grenze; k+=2) {
 +        bool hatTeiler = false;
 +        for (int t=1; primes[t]*primes[t]<=k; t++) {
 +            if (k%primes[t]==0) {
 +                hatTeiler = true;
 +            }
 +        }
 +        if (hatTeiler==false) {
 +            cout << k << endl;
 +            if (anzahl<maxprimes) primes[anzahl]=k;
 +            anzahl++;
 +        }
 +    }
 +    cout << anzahl << " Primzahlen bis " << grenze << endl;
 +
 +    return 0;
 +}
 +
 +</code>
 +</hidden>
 +
 +==== Sieb von Eratosthenes ====
 +Ein bool könnte mit einem einzigen Bit dargestellt werden. Tatsächlich werden aber meistens 1 Byte (8 Bits) Speicher dafür reserviert. In einem ersten Schritt wird ein Array von bool reserviert:
 +
 +<code cpp>
 +int n = 10000;  // Obere Grenze
 +bool prim[n];   // prim (true/false)
 +// Initialisierung
 +for (int i=0; i<n; i++) {
 +  prim[i]=true;
 +}
 +// Spezialfälle
 +prim[0] = false;
 +prim[1] = false;
 +
 +int wegmit=2;  // Erste Primzahl zum rausstreichen
 +while (wegmit*wegmin<n) {    // Bis zur Wurzel von n
 +   // TODO: Alle Vielfachen von wegmit wegstreichen
 +   // TODO: Nächste Primzahl im Array bestimmen.
 +}
 +</code>
 +
 +
 +
 +===== Lektion 2 (Freitag 24. August 2018) =====
 +==== For-Schleife ====
 +<code c++>
 +   for(INITIALISIERUNG;  BEDINGUNG VOR DER SCHLAUFE;   AKTION NACH DER SCHLAUFE) {
 +       // Dinge, die wiederholt werden
 +   }
 +</code>
 +Typischerweise sieht eine For-Schleife so aus:
 +<code c++>
 +  for (int i=0; i<100; i++) {
 +     // Tu was mit i
 +  }
 +  // ACHTUNG: i existiert hier nur in der Schleife und nicht ausserhalb!
 +</code>
 +
 +=== Spezialfälle ===
 +<code cpp>
 +   for(;;) {
 +      // Endlosschleife
 +   }
 +   
 +   // Das sollte man nie so schreiben, sondern wie?
 +   for (int i=0, j=0; i<10; i+=(j==9?1:0), j=(j+1)%10) {
 +      cout << i << ", " << j << endl;
 +   }
 +   // Besser:
 +   for (int i=0; i<10; i++) {
 +      for (int j=0; j<10; j++) {
 +        cout << i << ", " << j << endl;
 +      }
 +   }
 +   
 +</code>
 +
 +==== Code lesen ====
 +
 +Was macht das folgende Programm?
 +<code c++>
 +#include <iostream>
 +
 +using namespace std;
 +
 +int main()
 +{
 +    for (int i=0; i<32; i++) {
 +        if (i % 3 == 0) {
 +            cout << "Dreierzahl" << endl;
 +        } else {
 +            cout << i << endl;
 +        }
 +    }
 +    return 0;
 +}
 +</code>
 +
 +==== FizzBuzz ====
 +Schreiben Sie ein Programm, das die Zahlen von 0 bis und mit 31 ausgibt. Anstelle jeder Zahl, die durch 3 teilbar ist, soll "Fizz" ausgegeben werden, anstelle jeder Zahl, die durch 5 teilbar ist, soll "Buzz" ausgegeben werden. Ist die Zahl sowohl durch 3 als auch durch 5 teilbar, soll "FizzBuzz" ausgegeben werden.
 +
 +<hidden Lösungsvorschläge>
 +Mark
 +<code cpp>
 +#include <iostream>
 +
 +using namespace std;
 +
 +int main()
 +{
 +    for (int i=0; i<32; i++) {
 +        if (i % 15 == 0) {
 +            cout << "FizzBuzz" << endl;
 +        } else if (i % 5 == 0) {
 +            cout << "Buzz" << endl;
 +        } else if (i % 3 == 0) {
 +            cout << "Fizz" << endl;
 +        } else {
 +            cout << i << endl;
 +        }
 +
 +    }
 +    return 0;
 +
 +}
 +</code>
 +
 +Lukasz
 +<code cpp>
 +#include <iostream>
 +
 +using namespace std;
 +
 +int main()
 +{
 +for (int i=1; i<32; i++) {
 +    if (i%3==0 && i%5==0) {
 +        cout << "FizzBuzz" << endl;
 +    }
 +    else if (i%5==0) {
 +        cout << "Buzz" << endl;
 +    }
 +    else if (i%3==0) {
 +        cout << "Fizz" << endl;
 +    }
 +    else if (i==i) {
 +        cout << i << endl;
 +    }
 +    }
 +    return 0;
 +}
 +</code>
 +
 +Noah
 +<code cpp>
 +#include <iostream>
 +
 +using namespace std;
 +
 +int main()
 +{
 +    for (int i=1; i<32; i++) {
 +        if (i % 3 == 0 && i % 5 == 0) {
 +            cout << "FizzBuzz" << endl;
 +        }
 +        else if (i % 5 == 0) {
 +            cout << "Buzz" << endl;
 +        }
 +        else if (i % 3 == 0) {
 +            cout << "Fizz" << endl;
 +        }
 +
 +        else {
 +            cout << i << endl;
 +        }
 +    }
 +    return 0;
 +}
 +</code>
 +
 +Blc: (so nicht zu empfehlen):
 +<code cpp>
 +#include <iostream>
 +
 +using namespace std;
 +
 +int main()
 +{
 +    for (int i=0; i<32; i++) {
 +        cout << (i%3==0?"Fizz":"") << (i%5==0?"Buzz":"") << ((i%3)*(i%5)?to_string(i):"") << endl;
 +    }
 +
 +   return 0;
 +}
 +</code>
 +
 +</hidden>
 +
 +
 +}
 +
 +
 +==== Kontrollstukturen ====
 +if, for, while, break
 +
 +
 +Verifizieren Sie die ersten 8 Einträge der Tabelle auf  https://primes.utm.edu/howmany.html