Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| lehrkraefte:blc:informatik:ffprg2-2018:ffprg2-2018 [2019/01/18 15:18] – [7-Segment-Anzeige-Demo] Ivo Blöchliger | lehrkraefte:blc:informatik:ffprg2-2018:ffprg2-2018 [2019/01/25 14:34] (current) – [Assembler und Hacking (Stackoverflow)] Ivo Blöchliger | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== https:// | ||
| + | ====== 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:// | ||
| + | * Dokumentation: | ||
| + | |||
| + | ====== Hacking ====== | ||
| + | ===== XSS: Cross Site Scripting ===== | ||
| + | https:// | ||
| + | |||
| + | ===== Assembler und Hacking (Stackoverflow) ===== | ||
| + | Ein aktueller Hack vom letzten Chaos Computer Congress: https:// | ||
| + | |||
| + | |||
| + | * https:// | ||
| + | |||
| + | ===== 7-Segment-Anzeige-Demo ===== | ||
| + | Die 3 Segmente sind an den Adressen 253, 254 und 255, die Bits beginnen oben, dann im Urzeigersinn, | ||
| + | <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 | ||
| + | </ | ||
| + | |||
| + | 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 | ||
| + | </ | ||
| + | |||
| + | Der L0L-Dreizeiler | ||
| + | <code asm> | ||
| + | MOV [253], 0111000b | ||
| + | MOV [254], 0111111b | ||
| + | MOV [255], 0111000b | ||
| + | </ | ||
| + | |||
| + | |||
| + | Manipulierte Rücksprungadresse | ||
| + | |||
| + | <code asm> | ||
| + | mov A, ' | ||
| + | start: | ||
| + | inc A ; Erhöht den Inhalt vom Register A um 1 | ||
| + | mov [232], A ; | ||
| + | call bla ; | ||
| + | ruecksprung: | ||
| + | hlt ;Halt | ||
| + | |||
| + | |||
| + | bla: | ||
| + | mov [253], A ;Alle 7 Bits für 7-Segment-Anzeige | ||
| + | mov [SP+1], start ; Rücksprungadresse überschreiben | ||
| + | ret ; | ||
| + | </ | ||
| + | |||
| + | |||
| + | 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 | ||
| + | |||
| + | </ | ||
| + | ===== 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 | ||
| + | </ | ||
| + | |||
| + | Schaffen Sie es, indem Sie nur die DB-Zeile anpassen (das wäre so quasi der User-Input), | ||
| + | |||
| + | <hidden Lösungsvorschlag> | ||
| + | Mit Rücksprung direkt in die DB-Konstante (Adresse 0x02) | ||
| + | <code asm> | ||
| + | DB " | ||
| + | </ | ||
| + | Oder mit Rücksprung in die kopierten Daten an der Adresse 0xdc: | ||
| + | <code asm> | ||
| + | DB " | ||
| + | </ | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | ===== 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 | ||
| + | </ | ||
| + | |||
| + | ===== Roborobo-Fernbedienung / Ivobot ===== | ||
| + | * RoboRobo-Fernbedienung: | ||
| + | * IvoBot: | ||
| + | * {{ : | ||
| + | * [[https:// | ||
| + | * Seite der BU2 2017 [[lehrkraefte: | ||
| + | |||
| + | |||
| + | ===== 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, | ||
| + | |||
| + | Der 2. Anschluss wird am Arduino an einen der " | ||
| + | <code c++> | ||
| + | int wert = analogRead(A0); | ||
| + | </ | ||
| + | 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, | ||
| + | </ | ||
| + | |||
| + | === 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(" | ||
| + | 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:// | ||
| + | * Auf den Schulcomputern einen Ordner auf C:\ anlegen und die IDE darin entpacken. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | <code cpp> | ||
| + | |||
| + | int ports[] = {12,11,10}; | ||
| + | int num = sizeof(ports)/ | ||
| + | |||
| + | void setup() { | ||
| + | // put your setup code here, to run once: | ||
| + | for (int i=0; i<num; i++) { | ||
| + | pinMode(ports[i], | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | // put your main code here, to run repeatedly: | ||
| + | for (int i=0; i<num; i++) { | ||
| + | digitalWrite(ports[i], | ||
| + | delay(100); | ||
| + | digitalWrite(ports[i], | ||
| + | } | ||
| + | delay(500); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Lektion 4 (Freitag 7. September 2018) ===== | ||
| + | ==== Arrays ==== | ||
| + | <code cpp> | ||
| + | // Nur für kleine Arrays! | ||
| + | int zahlen[10]; | ||
| + | zahlen[0]=2; | ||
| + | zahlen[9]=42; | ||
| + | | ||
| + | // Für grosse Arrays: | ||
| + | int grenze = 10000000; | ||
| + | bool* prim = new bool[grenze]; | ||
| + | |||
| + | delete[] prim; // Speicher wieder freigeben | ||
| + | </ | ||
| + | |||
| + | ==== Sieb von Erathostenes ==== | ||
| + | <hidden Lösungsvorschlag> | ||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | int grenze = 100000000; | ||
| + | bool *prim = new bool[grenze]; | ||
| + | cout << "Alloc finished" | ||
| + | // Initialisierung | ||
| + | for (int i=0; i< | ||
| + | prim[i] = i>1; | ||
| + | } | ||
| + | cout << "Init done " << endl; | ||
| + | int akt = 0; // Zahl zum Abstreichen | ||
| + | while (akt*akt< | ||
| + | while (!prim[++akt]); | ||
| + | for (int p=akt*akt; p< | ||
| + | prim[p] = false; | ||
| + | } | ||
| + | } | ||
| + | // Ausgabe der Liste | ||
| + | for (int i=0; i< | ||
| + | if (prim[i]) { | ||
| + | cout << i << endl; | ||
| + | } | ||
| + | } | ||
| + | // Speicher wieder freigeben | ||
| + | delete[] prim; | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Lektion 3 (Freitag 31. August 2018) ===== | ||
| + | ==== Wahrheitswerte '' | ||
| + | Das Ergebnis eines Vergleichs (z.B. mit ==, !=, <, >, etc. ist ein Wahrheitswert '' | ||
| + | <code cpp> | ||
| + | bool gleich; | ||
| + | gleich = (42==6*7); | ||
| + | if (gleich) { // Gleicher effekt wie gleich==true | ||
| + | cout << " | ||
| + | } else { | ||
| + | cout << " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Hinweis: Werden andere Typen als bool interpretiert, | ||
| + | |||
| + | ==== Primzahlen ausgeben ==== | ||
| + | Schreiben Sie ein Programm, das alle Primzahlen bis zu einer gegebenen Grenze ausgibt. | ||
| + | |||
| + | <hidden Lösungsvorschläge> | ||
| + | <code cpp> | ||
| + | #include < | ||
| + | #include " | ||
| + | |||
| + | 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< | ||
| + | bool hatTeiler = false; | ||
| + | for (int t=1; primes[t]*primes[t]< | ||
| + | if (k%primes[t]==0) { | ||
| + | hatTeiler = true; | ||
| + | } | ||
| + | } | ||
| + | if (hatTeiler==false) { | ||
| + | cout << k << endl; | ||
| + | if (anzahl< | ||
| + | anzahl++; | ||
| + | } | ||
| + | } | ||
| + | cout << anzahl << " Primzahlen bis " << grenze << endl; | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ==== 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; | ||
| + | bool prim[n]; | ||
| + | // Initialisierung | ||
| + | for (int i=0; i<n; i++) { | ||
| + | prim[i]=true; | ||
| + | } | ||
| + | // Spezialfälle | ||
| + | prim[0] = false; | ||
| + | prim[1] = false; | ||
| + | |||
| + | int wegmit=2; | ||
| + | while (wegmit*wegmin< | ||
| + | // TODO: Alle Vielfachen von wegmit wegstreichen | ||
| + | // TODO: Nächste Primzahl im Array bestimmen. | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | ===== Lektion 2 (Freitag 24. August 2018) ===== | ||
| + | ==== For-Schleife ==== | ||
| + | <code c++> | ||
| + | | ||
| + | // Dinge, die wiederholt werden | ||
| + | } | ||
| + | </ | ||
| + | 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! | ||
| + | </ | ||
| + | |||
| + | === Spezialfälle === | ||
| + | <code cpp> | ||
| + | | ||
| + | // Endlosschleife | ||
| + | } | ||
| + | |||
| + | // Das sollte man nie so schreiben, sondern wie? | ||
| + | for (int i=0, j=0; i<10; i+=(j==9? | ||
| + | cout << i << ", " << j << endl; | ||
| + | } | ||
| + | // Besser: | ||
| + | for (int i=0; i<10; i++) { | ||
| + | for (int j=0; j<10; j++) { | ||
| + | cout << i << ", " << j << endl; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | ==== Code lesen ==== | ||
| + | |||
| + | Was macht das folgende Programm? | ||
| + | <code c++> | ||
| + | #include < | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | for (int i=0; i<32; i++) { | ||
| + | if (i % 3 == 0) { | ||
| + | cout << " | ||
| + | } else { | ||
| + | cout << i << endl; | ||
| + | } | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== FizzBuzz ==== | ||
| + | Schreiben Sie ein Programm, das die Zahlen von 0 bis und mit 31 ausgibt. Anstelle jeder Zahl, die durch 3 teilbar ist, soll " | ||
| + | |||
| + | <hidden Lösungsvorschläge> | ||
| + | Mark | ||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | for (int i=0; i<32; i++) { | ||
| + | if (i % 15 == 0) { | ||
| + | cout << " | ||
| + | } else if (i % 5 == 0) { | ||
| + | cout << " | ||
| + | } else if (i % 3 == 0) { | ||
| + | cout << " | ||
| + | } else { | ||
| + | cout << i << endl; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | return 0; | ||
| + | |||
| + | } | ||
| + | </ | ||
| + | |||
| + | Lukasz | ||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | for (int i=1; i<32; i++) { | ||
| + | if (i%3==0 && i%5==0) { | ||
| + | cout << " | ||
| + | } | ||
| + | else if (i%5==0) { | ||
| + | cout << " | ||
| + | } | ||
| + | else if (i%3==0) { | ||
| + | cout << " | ||
| + | } | ||
| + | else if (i==i) { | ||
| + | cout << i << endl; | ||
| + | } | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Noah | ||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | for (int i=1; i<32; i++) { | ||
| + | if (i % 3 == 0 && i % 5 == 0) { | ||
| + | cout << " | ||
| + | } | ||
| + | else if (i % 5 == 0) { | ||
| + | cout << " | ||
| + | } | ||
| + | else if (i % 3 == 0) { | ||
| + | cout << " | ||
| + | } | ||
| + | |||
| + | else { | ||
| + | cout << i << endl; | ||
| + | } | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Blc: (so nicht zu empfehlen): | ||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | for (int i=0; i<32; i++) { | ||
| + | cout << (i%3==0?" | ||
| + | } | ||
| + | |||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | ==== Kontrollstukturen ==== | ||
| + | if, for, while, break | ||
| + | |||
| + | |||
| + | Verifizieren Sie die ersten 8 Einträge der Tabelle auf https:// | ||