Assembler Assembler Einstieg

Lohnt sich Assembler zu lernen?

  • Ja

    Stimmen: 10 100,0%
  • Nein

    Stimmen: 0 0,0%

  • Umfrageteilnehmer
    10

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Moin Moin,

bis jetzt habe ich nur in "C" programmiert. Ein einigen Ecken und Kanten, wird es dann doch mal Zeitkritisch.
Nun habe ich mich entschlossen, doch ein bisschen Assembler zu lernen.. Macht das Sinn oder sollte ich eher bei "C" bleiben?

Gibt es ein Buch was ihr mir empfehlen könnt?

Danke schon mal ;)
 
Oho...

Also grundsätzlich würde ich empfehlen, sich zumindest mit ASM zu beschäftigen. Man muß seiner Lieblingssprache ja nicht unbedingt den Rücken zu kehren, aber ASM ist eben 1:1 mit Maschinencode ersetzbar. Du weißt also, was der Controller wann wie macht, wielange er braucht usw.
Mit diesem Verständnis kannst Du natürlich auch in Hochsprachen … vermuten, was in Wirklichkeit hinter irgendwelchen Prozeduren steckt.
Außerdem kannst Du, wo's nötig ist, ASM in Hochsprachen einbinden (in Bascom direkt, in C wohl auch direkt, oder dort sogar durch linken (?) von ASM und C - Teilprogrammen (wobei dann die ASM-typische Kontrolle über die IVT verloren geht)).

Entsprechend fallen meine Literaturempfehlungen aus:
  • Das jeweilige Controllerdatenblatt
  • Gerhard Schmidt's AVR-Assembler-Tutorial (insbesondere das PDF zum Download)
  • Oldmax's Assembler-Thread (sollte ja mal ein Buch draus werden - gibt's das inzwischen?)
  • unverzichtbar nebenbei das AVR Instruction Set
  • (Hier im Forum fragen - das weckt uns "alte Säcke" vielleicht auf;))

Viel Erfolg.
 
Hi,
Ich wollte letztens diese hochmodernen WS2812 LEDs ansteuern. Da bin ich direkt an die Grenzen von den ganzen gekommen. Das Timing hat einfach nicht gepasst.. Da kam mir in den Sinn eine Funktion in C mit Inline Asembler zu schreiben.. Da wollte ich drauf aufsetzen.
 
Ich schließe mich an, ja.
Alleine schon um die Hardware kennen zu lernen und um zu wissen was "under the hood" so gemacht wird. Grade bei Microcontrollern bietet sich das an, gleich auf die wirklichen CPU's wie x86 oder x64 zu gehen wäre wohl für jeden zu viel.
Mal vom präzisem Timing angesehen, was unter Hochsprachen recht abenteuerlich werden kann, ist es aber recht egal was man nachher für seine Projekte wirklich nutzt. Allerdings hilft es einem halt extrem bei der Fehlersuche wenn man weiß wofür man programmiert, statt nur von einer "Black Box" auszugehen, mit blindem Vertrauen, "Ach, C/Bascom/LunaAVR/... macht das schon".
 
diese hochmodernen WS2812 LEDs ansteuern. […] an die Grenzen von den ganzen gekommen. Das Timing hat einfach nicht gepasst.. […] C mit Inline Asembler zu schreiben.. Da wollte ich drauf aufsetzen.
Also grundsätzlich finde ich die seriell mit SPI ansteuerbaren LEDs interessanter, aber gut...
Scheint ein lohnenswertes Projekt zu sein - ich würde vorher ein (ASM) Programm anstreben, welches vom UART die Daten entgegennimmt, und entsprechend die LEDs ansteuert.

ABER: Die ersten Schritte sind natürlich (mMn):
  • ein leeres Programm ("Anhalten", ggf mit NOP - reicht im Simulator)
  • nur einmal (statisch) irgendwelche Zustände auf irgendwelche Beine schalten (LEDs)
  • Zustände von Eingängen lesen (Polling), und auf Ausgängen wiedergeben
  • gelesene Zustände invertiert wiedergeben
  • LED mit Warteschleife blinken lassen
  • Taster zum in-/dekrementieren einer "Zahl" verwenden (Entprellung via Warteschleife), Ausgabe auf mehrere LEDs (Port)
  • äquivalent dazu eine LED "durch den Port schieben"
  • UART Transmitter scharfmachen, Zahl senden.
  • UART Reciever scharfmachen, empfangene Zahl binär ausgeben.
  • LED timerbasiert blinken lassen (Polling, PWM)
  • Frequenz und/oder Pulsweite durch den UART vorgeben.
  • Irgendwas berechnen lassen (Summe(0..n) zB)
Ähnliche Spielereien sind natürlich auch die anderen Hardware-Module betreffend denkbar.

P.S.:
durch linken (?) von ASM und C - Teilprogrammen
Da hat @Mikro23 hier die wesentlichen Dinge erklärt.
 
Taster zum in-/dekrementieren einer "Zahl" verwenden (Entprellung via Warteschleife), Ausgabe auf mehrere LEDs (Port)
Mit dem Entprellen habe ich mir schon in "C" einen Daumen abgebrochen.. Das dann noch in Assembler? Schauen wir mal.. Heute kommt hoffentlich mein Buch daheim an und dann kann ich richtig loslegen..
nur einmal (statisch) irgendwelche Zustände auf irgendwelche Beine schalten (LEDs)
Das werde ich als erstes mal versuchen.
 
Hi Janiiix,

ich bin im Zweifel, ob dieses Buch seinen Preis wert sein wird.

PC-Assembler ist zwar grundsätzlich auch Assembler - aber schon die Mnemonics sind mehrheitlich nicht identisch mit denen von AVR-ASM. Sobald es um Hardware geht, kannst du es wegen der völlig anderen Rechnerarchitektur komplett vergessen.

Gruß
Pirx
 
Es kann doch im allgemeinen nicht schaden auch für den PC die Befehle zu kennen oder? Die Sprache bzw. der Aufbau des Programmes sollte gleich sein?
 
Es kann doch im allgemeinen nicht schaden auch für den PC die Befehle zu kennen oder?
Nein. Aber einen PC in Assembler programmieren? Das willst Du Dir nicht antun.
Die Beschreibung der Befehle findet man im web. Dafür muß man kein Buch kaufen.
Die Sprache bzw. der Aufbau des Programmes sollte gleich sein?
PC-Programme werden im Allgemeinen in C++ oder noch höheren Sprachen geschrieben. Sie sind auch meistens so umfangreich, daß mehrere Programmierer an einem Programm arbeiten. Das macht keiner mehr in Assembler.
 
Also ob Du Dir mit dem Buch 'n Gefallen tust, kann ich nicht einschätzen.

Die AVR:
  1. sind "Harvard Architektur" Controller - Programmspeicher und "Arbeitsspeicher" sind getrennt. Du kannst zwar auch Daten vom ProgramFlash ins SRAM laden, und sogar umgekehrt Daten vom SRAM in den Flash, aber der Instruction-Decoder ist NUR an den Flash angebunden, und verarbeitet NUR was DA steht.
  2. sind RISC-Controller - RISC steht für Reduced InStruction Core. Es gibt also weniger Befehle (die zu unterscheiden sind, vom Decoder - von Dir natürlich auch)
  3. besitzen eine ALU (Rechenkern), die auf 32 Rechenregister zugreifen kann
Der AVR-Assembler ist (natürlich) genau auf die AVR ausgelegt.

ich wohl mit einem TINY2313 und nem MEGA8
Der Tiny2313 ist für den Anfang gar nicht so schlecht. Noch verhältnismäßig übersichtlich, einen kompletten (8Bit) und einen 7Bit Port, später dann noch UART. Zwei Timer, PWM,...
Für den Anfang wäre vielleicht der Tiny13 oder der AT90S2343 noch einfacher (beim Tiny2313 sind die 64 I/O-Register schon recht voll - aber da mußt Du halt einfach ignorieren, was Du noch nicht durchhast).
Den Tiny2313 gibts auch als A-Version - mit relevanten Unterschieden.

Als erstes solltest Du mal einen Blick in das Controller-Datenblatt (complete) werfen. Recht weit am Anfang findet sich ein Block-Diagramm des Controllers. Beim Tiny2313 ist da schon recht viel Peripherie um den Datenbus rum (oben und unten die Ports, rechts die restlichen Module).
Links vom Datenbus ist der eigentliche CPU-Core dargestellt, und der wird etwas später im DB nochmal genauer erklärt.
Diese ersten Seiten des DB solltest Du mal durcharbeiten (Interrupt/Reset/Eeprom dabei nur überfliegen).

P.S.: Dabei hilft Dir vielleicht auch Dinos Dampfmaschin-Thread (hatte ich oben vergessen).

P.P.S.:
es wäre dieses buch geworden
Da war Jan wohl zu ungeduldig - aber meiner Meinung nach gehts auch ohne Buch...
 
Ihr habt ja recht. Habe das Buch heute wieder zurück geschickt. Ist doch ein bisschen teuer. Habe heute morgen meinen Laserdrucker entstaubt und direkt mal das Assembler Tutorial von www.mikrocontroller.net ausgedruckt. Das wird für den Anfang auch erstmal reichen..
 
Hmm…

welcher 2313 isses denn nun? Mit oder ohne A?
Welches AVR-Studio?

Hast Du einen Blick in Dinos Thread geworfen, und in die ersten Seiten des Controller-Datenblattes?
Dir muß erstmal klar sein, wie der Controller die Instruktionen im Flash abarbeitet, wie die Instruktion-Maschinerie mit ALU, den Rechenregistern und dem SREG verbunden ist.
Dann würde ich als erstes den wahnsinnig komplizierten Befehl NOP vorstellen.
Also mal ein Programm mit zehn NOPs durch den Simulator jagen.
Die nächste Aufgabe wäre, dieses Programm - sagen wir nach dem vierten NOP - auf der Stelle hüpfen zu lassen.
Was brauchst Du dazu?
Wie geht das?

P.S.: Wie Du sicherlich gesehen hast, beinhaltet das AVR-Instruction-Set 142 Instruktionen. Allerdings stehen davon nicht alle Instruktionen allen Controllern zur Verfügung.
Abgesehen davon sind viele Instruktionen eigentlich keine einzelnen Instruktionen, sondern nur Spezialfälle anderer Instruktionen - nur eben mit 'nem eigenen Namen.
Ich habe mal grob sortiert, was es so an Instruktionen gibt, was so'n AVR eigentlich kann.
Soll ich hier was dazu schreiben?
 
welcher 2313 isses denn nun? Mit oder ohne A?
Dafür müsste ich diesen jetzt erstmal raus suchen, habe hier gerade einen ATmega32 neben mir legen. Der muss als erstes dran glauben!
Welches AVR-Studio?
Ich benutze das aktuellste Atmel Studio ( 7.x )
Hast Du einen Blick in Dinos Thread geworfen, und in die ersten Seiten des Controller-Datenblattes?
Habe ich schon rein geschaut als in das Datenblatt aber noch nicht intensiv genug. Wie gesagt habe mir ja heute morgen, das Tut. ausgedruckt und werde mir das jetzt mal zur Brust nehmen. Hier ist der Link dazu
https://www.google.de/url?sa=t&rct=...05_08_v2.pdf&usg=AOvVaw0UTFpbCf6aqKG2YclNPw-5
Soll ich hier was dazu schreiben?
Ja bitte! Ich bin dankbar für jegliche Hilfe..
 
Was meinen die eigentlich mit
6.3 Sprung zu beliebiger Adresse
Der AVR besitzt keinen Befehl, um direkt zu einer Adresse zu springen, die in einem Registerpaar gespeichert ist.
Was denn nun?
Direkt auf eine fest (konstant) vorgegebene Adresse (Jmp/Rjmp), oder auf eine - indirekt in zwei Registern abgelegte - zur Laufzeit variable Adresse (Ijmp/Eijmp)
Klar kann man das auch wie dort mit angedeutet Push-Push-Ret über den Stack umgehen, aber auch dann ist die Adresse indirekt im Registerpaar bzw anschließend auf dem Stack abgelegt, vor dem Sprung...

BTT:
einen ATmega32 neben mir legen. Der muss als erstes dran glauben!
Auch den gibt's als A/PA oder so...
Dann mußt Du eben dessen DB-Anfang studieren - ist eh bei allen AVR nahezu gleich...
Das Block-Diagramm ist natürlich komplexer...
 
Soll ich hier was dazu schreiben?
Ja bitte! Ich bin dankbar für jegliche Hilfe..
Ok, im Mega32-Datenblatt auf Seite drei das Blockschema des Controllers.
Den Datenbus als dicken Pfeil. Dieser verbindet die Peripherie (die Beine oben und unten, die digitalen Schnittstellen, Timer usw - aber auch SRAM und Eeprom) mit der Eigentlichen CPU (der extra eingerahmte Bereich links).
Im CPU-Block erkennst Du den Programm-Counter, Instruction-Register und -Dekoder, die 32 Rechenregister (General Purpose Register), die ALU und das Statusregister.
Nach einem Reset zeigt der Programmcounter auf Adresse null im Flash, dessen Inhalt wird als erstes in den Instruction-Decoder geladen. Mit jedem weiteren Takt wird nun eine Instruktion abgearbeitet, und die nächste geladen (jaja, vereinfacht, nicht alle Instruktionen kommen mit einem Takt aus...).
Läuft der Programmcounter auf null über, wird eben da weitergemacht.
Soll das Programm in irgendeiner Form verzweigt werden, muß (mit einer entsprechenden Instruktion) eben die entsprechende Adresse in den Programmcounter geladen werden.

Ich hatte oben bereits die Instruktion NOP angedeutet - hier mal eine Zusammenfassung aller Instruktionen - was kann so'ne AVR-CPU eigentlich?
Dem Instruction Set folgend beginne ich mit den arithmetischen/logischen Operationen. Allgemein formuliert nimmt die ALU den Inhalt eines oder zweier Rechenregister, rechnet damit irgendwas, und legt das Ergebnis (meist) im ersten der beiden Register ab. Dabei werden (fast) jedesmal irgendwelche Bits im Statusregister manipuliert, die in weiteren Operationen miteinbezogen bzw ausgewertet werden können.
Also los, die ALU kann:
  • zwei Register miteinander Addieren (ADD), es kann ein vorher ermittelter Überlauf (das Carry aus dem SREG) miteinbezogen werden (ADC).
  • analog dazu zwei Register subtrahieren, ggf auch hier mit Carry (SUB bzw SBC)
  • von einem Register eine Konstante abziehen, auch hier ggf mit Carry (SUBI, SBCI)
  • auf ein Doppelregister (16bit) eine Konstante addieren (ADIW) bzw von dort subtrahieren (SBIW)
  • zwei Register bitweise logisch verknüpfen (AND, OR, EOR)
  • ein Register mit einer Konstante bitweise logisch verANDen (ANDI) bzw verORen (ORI)
  • von einem Register das Einer- (COM) bzw Zweierkomplement (NEG) bilden
  • ein Register inkrementieren (INC) bzw dekrementieren (DEC)
  • zwei Register multiplizieren, und zwar beide unsigned (MUL), beide signed (MULS) oder eins singned und eines unsigned (MULSU)
  • analog dazu fraktionelle Multiplikation (FMUL, FMULS, FMULSU)
  • (Bei XMEGAS kann mit DES ein Iterationsschritt im Data Encryption Standard ausgelöst werden)
Hierher gehören eigentlich auch noch folgende Bit-Funktionen, die ALU kann:
  • die Bits eines Registers logisch nach links (LSL) oder rechts (LSR) schieben, dabei rutscht eine null auf die leere Stelle, das rausgeschobene Bit fällt ins Carry
  • statt der null kann auch das Carry auf die leere stelle gerollt werden (ROL bzw ROR)
  • die Bits eines Registers arithmetisch nach rechts schieben (ASR, Integerdivision durch zwei)
Und der Vollständigkeit halber noch die drei Vergleiche - das sind in Wirklichkeit nur Subtraktionen ohne Zurückschreiben des Ergebnisses. Trotzdem wird das SREG manipuliert:
  • CP vergleicht (subtrahiert) zwei Register
  • CPC subtrahiert zusätzlich das Carry
  • CPI subtrahiert eine Konstante vom Register
Streng genommen haben wir damit alle Instruktionen, in denen die ALU durch eine Operation Bits im SREG manipuliert.
(hinter SBR verbirgt sich in Wirklichkeit ORI, hinter CBR ANDI, CLR ist eigentlich ein EOR, SER ein LDI (also gar keine Rechenoperation, deswegen kommt auch das Zero nicht), TST ist ein AND)

Verzweigungen kommen morgen (denk ich - bitte freilassen)
 
@LotadaC
Das werde ich mir nachher mal in Ruhe durchlesen..

Hier ist schon mal ein ganz kleiner Anfang..


CodeBox Assembler
;
; asm versuche.asm
;
; Created: 09.09.2018 10:33:59
; Author : Jan 
;

 .def tmp8 = r16
 
 .equ F_CPU   = 16000000 ; Systemfrequenz
 .equ F_DIV   = 1024  ; Systemteiler
 .equ delay10ms  = ( F_CPU / F_DIV ) / 1000 ; Takte für ~10ms

 
 .equ LED_DDR_PORT = DDRD ; Led DatenRichtungsRegister
 .equ LED_PORT  = PORTD ; Led Port
 .equ LED_bp   = 4  ; Led Bit Position


initHardware:
    /* StackPointer
    *
    * Der Stackpointer wird am Ende des RAM´s angelegt.
    * Von dort aus wächst er je nach Bedarf nach "hinten" raus.
    *
    * Einige Controller initalisieren den Stack schon automatisch..
    * Der ATmega32 ist noch keiner davon...
    * Wichtig! Der Stack muss vor aufruf eines Unterprogrammes oder 
    * einen eingehenden / auftretenden Interrupt initalisiert werden.
    *
    */
    ldi tmp8 , high(ramend) ; Stackpointer initalisieren ( high Byte von der Adresse )
    out sph , tmp8 ; Addresse übergeben

    ldi tmp8 , low(ramend) ; Stackpointer initalisieren ( low Byte von der Adresse )
    out spl , tmp8 ; Addresse übergeben

    //ldi tmp8 , 1<<LED_bp ; DatenRichtungsRegister Bit setzen
    //out LED_DDR_PORT , tmp8 ; Wert an DDRx übergeben
    sbi  LED_DDR_PORT , LED_bp ; einzelnes Bit setzen

    rcall ledOff ; Welcher Sprung ist dafür jetzt besser geeignet?


ledOff:  
    cbi LED_PORT , LED_bp
    ijmp

ledOn:   sbi LED_PORT , LED_bp
    ijmp


P.s

Wie berechne ich denn jetzt eigentlich mehr oder weniger genau ne Zeitschleife? Da spielen die Takte von jedem Befehl ja eine Rolle mit, gibt es da einen Trick?
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)