Archiv für den Monat März 2012

Elektro

Mit den Nerds Musik machen ist in etwa genau das, was ich mir darunter vorgestellt hatte: Keine Instrumente, keine Melodie, kein Ton, kein Bullshit.
Stattdessen ein Terminal, lautes Rauschen und Knattern und Pieptöne die den schlimmsten Mono-Klingeltönen an Markerschütterung in nichts nachstehen. Welch ein Spaß!

Ich hatte ja schon im letzten Artikel erwähnt, dass bei Linux alles eine Datei ist, was es so schön hackbar macht. Nicht nur meine schlampig geschriebene To-Do-Listen und Uninotizen sind in Dateiform gespeichert, sondern sogar die Hardware ist als Datei darstellbar. So auch die Tastaturbelegung und meine Grafikkarte sind offene Gefäße in die ich etwas reinpacken kann.

Und was macht ein Nerd, wenn er einen offenen Topf bei sich in der Wohnung findet? Er bestellt etwas beim Asiaten nebenan!

Naja, unabhängig davon versuchten wir also verschiedene Dateien wiederum in die Hardwaredateien zu schreiben. Als erstes schickte ich eine mp3-Datei in den Frame Buffer. Heraus kam folgende Pixelkotze:

Was ich aber nicht wusste war, dass das wahre erbrochene Pixelchaos erst dann entsteht, wenn ich eine random-byte-Datei dafür verwende! Das sieht dann nämlich so aus:

Das yougrow-Lied war also tatsächlich als das Lied das es ist dargestellt und gewissermaßen nicht verfremdet. Interessant ist daran, dass ich also die yougrow-Datei wirklich sehen und ihr Muster erkennen konnte. Oder theoretisch könnte. Was interessante Gedanken zur Perzeption von Musik zulässt.

Der Haupteil des Abends war aber dem Schreiben eines eigenen Musikprogramms gewidmet. Hier, “Musik” heißt das Programm:

.globl _start
#.lcomm buffer, 100
buffer:
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
.byte 0,255,0,255,0,255,0,255,0,255
_start:
pushl $buffer
pushl $100
loop:
call play
 jmp loop
movl $1, %eax
movl $0, %ebx
int $128

Das Programm schreibt die Bytes in einen Speicherbereich und dessen Inhalt wird an das Soundkartendevice ( /dev/dsp ) geschickt. Die Funktion “play” die in der loop aufgerufen wird sieht so aus:

datei:
 .ascii "/dev/dsp"

.globl play
play:
movl $5, %eax
movl $datei, %ebx
movl $1, %ecx
int $0x80
pushl %eax
movl %eax, %ebx
movl $4, %eax
movl 12(%esp), %ecx
movl 8(%esp), %edx
int $0x80

Bei den Bytes gibt es drei Komponenten, die bestimmen, was für ein Geräusch (aka Musik) ausgegeben wird. Dafür ist wichtig zu verstehen, dass die Bytes in Wellen geordnet sind. Das heißt eine Welle geht in diesem Falle von 0 über 255 und dann wieder zur 0.

Der Abstand zwischen den einzelnen Wellen ist bestimmend für die Höhe des Tons. Die Menge der Bytes, die ich insgesamt hineinschreibe in den Framebuffer bestimmt die Länge.
Und die Lautstärke des Tons wird durch die Amplitude der Welle bestimmt. In diesem Falle 255 (von null bis 255). Das ist also lauter als 0-10-20-10-0…etc.

Nachdem wir über 9000 Bytes in den Buffer geschrieben haben konnten wir das Programm assemblern, mit der zugehörigen Funktion linken und dann ausführen. Es schreibt die Bytes nach /dev/dsp und zu hören ist der 0,5-Sekunden lange Ton von ein paar Bytes. Innerlich weinten wir alle ein bisschen, gerührt vom süßlichen, herzerwärmenden Klang wenn der Avatar in diese scheiß Falle mit den Spitzen fällt, stirbt und dann schlecht animiert aus dem Bild springt.

Nach dieser Deromantisierung von Allem was ich in 10 Jahren Geigenunterricht gelernt habe (als ob) ging ich mich betrinken und erzählte meinen mittlerweile sehr rar gewordenen Nicht-Nerd-Freunden davon, wie ich gerade Musik machte. Und stellte fest, dass der Ansatz, Wellen mit Bytes zu erzeugen und an den Speaker zu schicken ne verflucht spannende Geschichte ist. Oder sein kann. Also wenn ich erstmal das mit den Sys-Calls verstanden habe. Und eine vernünftige Funktionenbibliothek hab. Wenn ich wieder Zeit hab!

Also wenn ich erstmal wieder nüchtern bin und Assembler beherrsche, dann…!

Ein U2665 für Macs!

geplanter  Beginn: 14:15
tatsächlicher Beginn: 14:07
Delay: -8 min

Den ungewöhnlichen Delay kann ich damit erklären, dass wir aufgrund meiner ääääh…Schlafstörungen während der Programmiersessions beschlossen, uns schon Nachmittags zu treffen. Das führt aber dazu, dass zwischen meiner Aufstehzeit und dem Progammieren sehr wenig Zeit ist, um etwas Anderes zu tun. Also eigentlich stehe ich auf und fahre dann zu Plom und mache gar nichts dazwischen.

Jedenfalls stand ich wohl 8 Minuten zu früh auf oder habe vergessen mir die Zähne zu putzen und irritierte damit Plom, der gerade noch in seinem neu geschaffenen “Haushalt”-Timeslot war. Gemeinsam untersuchten wir dann ein paar Items, die er aus seinem Schrank aussortiert hatte und nicht identifizieren konnte. Zwei Plastikbecher, eine Flasche Perlwein und ein paar Instantkaffeetüten. Achja, falls ihr Plom mal besuchen solltet, trinkt doch etwas Tee. Der ist nämlich schon sehr alt und wenn wir noch ein paar Jahre warten, müssen wir ihn wegschmeißen.
Wir gingen dann einkaufen und riefen Erlehmann mehrmals an, um mit ihm über Pizza zu reden und sanft daran zu erinnern, dass er doch bitte langsam losgehen sollte.

Als wir vom Pizzakaufen zurückkamen, lungerten ein paar Personen vor seiner Tür rum. Von Weitem dachten wir, es wäre dreimal erlehmann, dann beschlossen wir, dass das keine wünschenswerte Vorstellung ist. Aber die Vorstellung, dass ein paar coole Leute uns jetzt die Pausenpizza abknöpfen fanden wir auch nicht so gut. Im Endeffekt waren es junge Leute, die umgezogen waren und !achtung! einen IMac vor der Tür stehen ließen, auf dem “Mitnehmen! Funktioniert noch!” stand. Wir gingen daran vorbei und Plom fragte mich, ob ich einen bräuchte. Ich witzelte “Ja, zum Kaputtmachen”. Nach fünf Metern lief ich wieder raus und nahm ihn mit.
Da stand es nun, das pastellfarbene Monster, in Ploms Wohnung und wollte mit Strom gefüttert werden:

Plom wollte darauf programmieren und erlehmann schlug später vor, dass wir ihn doch als Spielecomputer verwenden könnten. Ich beharrte allerdings darauf, dass wir ihn einfach auseinandernehmen sollten. Aber interessanterweise müsste man dafür erstmal überlegen, ob Mac es schon damals unmöglich gemacht hat, seine Computer auseinanderzubauen. Vielleicht sollten wir ihn einschicken…
Im Moment konnten wir aber noch gar nicht so viel damit machen. Wir schalteten ihn ein, der hässliche Startton erklang, der schon vor 10 Jahren meine Eltern aus dem Schlaf riss, wenn ich nachts noch heimlich chatten wollte, und viel weiter kamen wir ohne Maus nicht. Wir suchten noch ein paar Shortcuts heraus, aber vertagten das Rumspielen mit dem Mac auf später. Vor allem auf das Rumspielen mit dem Terminal freue ich mich, da Mac OS ja Unix-basiert ist und ich all meine bescheidenen Shell Script Commands die ich kenne auch darauf anwenden kann.

Im Anschluss daran erzählte mir Plom noch die Erfolgsgeschichte von Unix und von den Grabenkämpfen, die sich um freie Software und Betriebssysteme drehten. Er erklärte mir auch, warum Linux bei Hackern so erfolgreich und beliebt wurde. Unter Anderem durch die Dateienstruktur. Bei Linux (oder auch Unix?) ist ja alles eine Datei. Allesallesalles. Der Cursor ist eine Datei, die Tastenbelegung ist eine Datei, der Lautsprecher ist eine Datei, deine Mutter ist eine Datei. Und da kann man reinschreiben!
Mit dem Wissen kann man dann z.B. die völlig sinnfreie Tastaturbelegung meines Lenovo T60 verändern. Oder Musik machen. Aber mehr dazu später. Die Tastaturdatei sieht so aus:

Den Keycode 66 veränderten wir erst in U2665 und dann so, dass ich “Less: <” und “Greater >” tippen kann. Die Taste 66 steht normalerweise für Caps Lock. Aber Caps Lock braucht kein Mensch und führt meistens ZU SOLCHEN MISSVERSTÄNDNISSEN in der schriftlichen Kommunikation (schrei doch nicht so!). < und > dagegen sind äußerst wichtige Symbole. Zum Beispiel hierfür: I <3 my Linux! Daher ist es auch reichlich bescheuert, dass die vorher fehlten.
Außerdem bekam ich endlich eine Pipe-Taste die dieses kunstreiche Zeichen ausgibt: |
Die pipe-Taste brauche ich, um verschiedene Programme miteinander zu verknüpfen. Und ja, man könnte sagen, dass wir dann ein paar Rohre verlegten. Aber das spielte für uns natürlich keine Rolle.

Nach dem Rumgespiele und “füttern unserer Tastaturtierchen”, wie Plom sie liebevoll nennt, setzten wir uns an das Programm toupper.s aus dem Buch. Ich sollte vielleicht erwähnen, dass das jetzt schon die dritte Sitzung war, die wir uns mit dem Programm rumärgerten. Beim ersten Mal habe ich angefangen zu heulen, das zweite Mal war zwar ähnlich anstrengend, aber wir schafften es zumindest, zwei von drei Syscalls zu codieren und zu verstehen. Diesmal brachten wir das Programm endlich zu einem Ende. Vielleicht auch weil ich es in dog.s umgenannt hatte:

Dieses Programm dient dazu, die Kleinbuchstaben einer Datei in Großbuchstaben zu verzaubern. Das macht es -grob gesagt- indem es die Zeichen im ascii-Code um 32 verringert, wodurch sie den Wert des entsprechenden Großbuchstaben annehmen. Das wird vielleicht klarer, wenn man sich mal die ascii-Tabelle anschaut:

         

Der Dezimalcode für ein kleines “a” ist 97. Verringert man diesen Wert um 32 landet man bei 65, also dem Dezimalcode für ein grooooßes “A”.
Lustigerweise hatte ich schon vor der ersten Session dazu mit jemandem über die Funktion des Programmes gesprochen und eigentlich nur aus Scheiß gesagt, dass man das ja so machen könnte, indem man die ascii-Charakter mit einer Zahl subtrahiert oder addiert, so dass der Großbuchstabe ausgegeben wird. Und ich dachte noch “Haha, genial, voll primitiv wahrscheinlich, aber sicher einfacher als das was der Autor sich überlegt hat, Plom und Erlehmann werden so stolz sein!”. Der Autor des Buches -unser ausgemachter Feind- machte mir einen Strich durch die Rechnung, weil er doch genau das anwendete. Aber ein ganz klein bisschen gefreut habe ich mich trotzdem, weil die Idee ja stimmte.

Das ist also die Automagie des Programms. Natürlich braucht es noch ein komplexeres Framework als das, z.B. muss ja auch eingegrenzt werden, für welche Charakter diese Operation durchgeführt werden soll. Das wird mit ein paar Konditionalen in Jump-Befehlen gelöst. Z.B. wenn der Wert, den ich gerade untersuche, kleiner als 65 ist, dann scheiß drauf und mach weiter im Programm bzw. schau dir das nächste Byte an.
Aber damit diese Operation überhaupt zum Zuge kommen kann, macht das Programm ersteinmal einen “Open” system call, dann einen “Read” system call und dann einen “Write” system call. Und dann wird unsere Datei “bdsm” in unser Terminal geschrieben. In Großbuchstaben!

Der Erste Versuch in dieser Shell scheiterte, weil ich offensichtlich den falschen Wert substrahiert hatte. Das musste dann geändert werden und raus kam ein gebrülltes “FICK MICH, FICK DICH, TROLOLOL”.

Das war auf jeden Fall viel schwerer als es aussieht. Kompliziert war es für mich vor allem, mir zu merken, was die verschiedenen Syscalls machen und was für Parameter sie brauchen und erzeugen und wo die nun wieder gespeichert werden. Nach der dritten Sitzung sah ich dann auch ein, dass ein paar Kommentare das Verstehen wesentlich leichter gemacht hätten.

Ach Assembler. Dass es in abstrakteren Sprachen dann sowas wie einen einzigen Befehl gibt, der genau das macht ist ja egal… wirklich total egal. TOTAL EGAL.
Wie schon zuvor gestaltete sich das Verstehen des Programms unheimlich zäh und schwierig und es flossen viele Tränen, Blut und Mate (Wahre Geschichte). Aber im Nachhinein wirkt das Programm dann umso simpler und ich umso erleuchteter.

Assembler lernen heißt auch Computer kennelernen heißt auch Siegen lernen.
Und zum Abschluss noch eine kleine Fotolovestory mit <3 für alle, die mir Assembler ausreden oder mir nicht zutrauen, damit umgehen zu können:

Danke Erlehmann!

Follow

Erhalte jeden neuen Beitrag in deinen Posteingang.

Schließe dich 99 Followern an