AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wie funzt der Assembler?

Ein Thema von Dax · begonnen am 20. Jan 2004 · letzter Beitrag vom 20. Jan 2004
Antwort Antwort
Dax
(Gast)

n/a Beiträge
 
#1

Wie funzt der Assembler?

  Alt 20. Jan 2004, 07:20
Ich kenne mich ja nicht besonders gut in Assembler aus, aber es interessiert mich schon ein bisschen. Anfings habe ich ein paar Funktionen in Assembler geschrieben, habe aber kläglich versagt. Jetzt bin ich darüber weg und interessiere mich für die Hintergründe.

Um es kurz zu machen: Wie funktionieren die ASM-Befehle (z.B. ADD, IMUL, MOV, AND, XOR, ...) im Prozessor (oder wie werden sie emuliert)?

BtW: Wenn jemand Schaltpläne für solche Befehle hat, die würde ich auch gerne mal sehen...

[edit=Sharky]Doppelposting nach Mitteilung von DAX gelöscht. Mfg, Sharky[/edit]
  Mit Zitat antworten Zitat
Alex_ITA01

Registriert seit: 22. Sep 2003
1.123 Beiträge
 
Delphi 12 Athens
 
#2

Re: Wie funzt der Assembler?

  Alt 20. Jan 2004, 08:36
hi dax
ich kann dir gerne ein paar befehle erklären die ich noch so im kopf habe
habe zu hause assemblerroutinen ohne ende liegen kann ich dir gern mal zeigen

also zu mov:
mov Ziel(Wohin),Quelle(Was)
mov ax,bx <--- du verschiebst das 16-bit register bx in das 16-bit register ax
mov ah,bh <----du verschiebst das 16-bit register bh in das 16-bit register ah
mov ah,bx <----FEHLER denn ein 16-Bit register passt nicht in ein 8-Bit register

Xor:
das einfach nur ne ganz logische verknüpfung die nichts anderes macht als eine Antivalenz durchzuführen
Bsp: Xor ax,ax <--- das setzt das Register ax einfach nur auf 0 (könntest also auch mov ax,0 schreiben)

AND:
kommt ebenfalls aus der Logik (der Ausgang wird nur 1 wenn beide Eingänge 1 sind)
Eingang1 Eingan2 Ausgang
0 0 0
1 0 0
0 1 0
1 1 1
ODER (OR):
kommt ebenfalls aus der Logik (der Ausgang wird nur 1 wenn EIN Eingang 1 ist)
Eingang1 Eingan2 Ausgang
0 0 0
1 0 1
0 1 1
1 1 1

da gibt es eben dann noch jede menge aber glaube da musste mal bei google suchen denn da steht das noch näher erläutert

ADD:
klar sagt der Name schon das addiert eben zwei register miteinander aber irgendwie weiß ich nicht mehr recht wo der ganzzahlige anteil und der rest hinfällt (lässt sich aber einfach per debugger herausfinden)

ich kann dir ja gerne mal die liste mitbringen wenn du sie magst
hoffe das hier oben reicht erstmal ein stück für dich
mfg alex
  Mit Zitat antworten Zitat
Brüggendiek

Registriert seit: 13. Dez 2002
Ort: Dortmund
275 Beiträge
 
Delphi 5 Standard
 
#3

Re: Wie funzt der Assembler?

  Alt 20. Jan 2004, 08:40
Hallo!

Das ist gar nicht so einfach zu beantworten!

Zunächst einmal: Der Prozessor hat keine Ahnung von Assembler-Befehlen und kennt sie auch nicht. Das einzige, was der Prozesor kennt, sind Maschineninstruktionen in Form von Zahlenwerten im Speicher.

In den Anfängen der Computerei mußten diese Zahlenwerte von Hand eingetragen werden. Schnell entwickelte man eine 'merkbare' Darstellung dieser Zahlen - ADD, XOR etc. lassen sich nun mal leichter merken und lesen als die Zahlen (üblicherweise sedezimal dargestellt).
Erschwerend kommt hinzu, daß ja auch z.B. Sprungadressen mit Zahlen dargestellt werden - bei den anfangs knappen Speichern mußte man genau ausrechnen, wo ein Unterprogramm zu Ende ist. Nebenbei: bei einer Maschine mit 48KB RAM und 8080-Prozessor gab es ein Schachspiel, das sich - gelinde gesagt - merkwürdig benahm - spielt mit den Figuren des Gegners weiter, man kann den König schlagen etc. Später wollte mal jemand von einem Spezialisten wissen, ob bei einem Disassembler das mehrfache Laden von Code an dieselbe Adresse berücksichtigt werden muß - diesen Schwachfug hatte er in dem Schachprogramm gefunden. Ursache: UP ab einer bestimmten Adresse geschrieben und das vorherliegende wurde dann etwas größer als geplant, deshalb von nächsten überschrieben.

Später kam man dann auf die Idee, die Umwandlung der Wörter in die Zahlen und besonders die Ausrechnung der Adressen vom Rechner erledigen zu lassen - Programm und Sprache nannte man ASSEMBLER. Die Assembler-Sprache ist immer maschinenabhängig, da ja bis auf wenige Ausnahmen alle Anweisungen zu Maschineninstruktionen werden.

Später wurden dann sogenannte Hochsprachen entwickelt it dem Ziel, die Programme auf mehreren Maschinen einsetzen zu können. Der Transfer geschieht natürlich auf Source-Ebene. Zunächst waren das 'problemorientierte Sprachen' - die geringen Hauptspeicher (ein Rechner mit 64KByte galt als Großrechner und kostete Millionen!) zwangen zur Beschränkung.
Für mathematisch-wissenschaftliche Probleme entstanden FORTRAN (Formular Translation) und ALGOL (Algorithmic Language), wärend für kommerzielle Aufgaben COBOL (Commerciel Businessy Oriented Language) entstand. Eine Textverarbeitung in FORTRAN war genauso ein Krampf wie Rechnen in COBOL - die COBOL-Rechnungen waren geschwätziges ASSEMBLER!
Code:
MULTIPLY A BY A GIVING X // A*A ist schneller als Quadrieren
MULTIPLY A BY B GIVING Z
ADD Z TO X
ADD Z TO X  //zweimal addieren schneller als mit 2 multiplizieren
MULTIPLY B BY B GIVING Z
ADD Z TO X
war die COBOL-Codierung für
Code:
x:=a*a + 2*a*b + b*b
a-quadrat plus 2 a b + b-quadrat - das denjenigen gesagt, die Programmieren in natürlicher Sprache bevorzugen.
COBOL: Programmiersprache für Programmierer mit eigenem Schreibbüro!
(Ob die Kommentare so gingen, weiß ich nicht. Vermutlich standen die in Spalte 73..80 der Lochkarte).

Später traten dann Universalsprachen wie SIMULA67 (für Simulationen 1967 in Norwegen aus ALGOL60 entwickelt, erste objektorientierte Sprache!!) und PASCAL auf.

Zum Teil werden die Sprachen interpretiert (BASIC), d.h. jede Zeile Source wird analysiert und ausgeführt. Andere wie Delphi werden compiliert, d.h. der Source wird analysiert und dann werden die nötigen Maschineninstruktionen notiert zur späteren Ausführung.

Zuletzt ging der Trend zu Maschinen- bzw. Betriebssystem-abhängigen Sprachen - die ganzen Windows-Controls gibt es ja z.B. unter Linux nicht.
Mit NET soll ja jetzt ein auf Compilat-Transfer aufsetzendes plattformübergreifendes System entstehen. Der Compiler erzeugt nicht Maschineninstruktionen, sondern einen Zwischencode, der dann 'live' in die Instruktionen der Zielmaschine compiliert wird. Vorteil gegenüber Hochsprachen-Interpretern: es ist zur Laufzeit keine Syntaxprüfung nötig, da diese beim Erzeugen des Zwischencodes durchgeführt wurde.


Die Verarbeitung der Maschineninstruktionen im Prozessor ist auch nicht so ganz einfach. Der Prozessor ist nämlich selber ein kleiner Computer! Er nimmt die Instruktionen aus dem Hauptspeicher, decodiert sie und startet die Ausführung. Heutzutage ist es üblich, mehrere Befehle in einer Pipeline zu bearbeiten: während der 1. Befehl seine Ergebnisse speichert, wird der 2. ausgeführt, der 3. decodiert und der 4. geladen. War der 1. Befehl ein Sprung, kann der Rest der Pipeline gelöscht werden - pech. Das geht sogar so weit heutzutage, daß die Prozessoren bei bedingten Sprüngen beide Zweige (Sprung und nicht-Sprung) vorab bearbeiten und das 'falsche' Ergebnis verwerfen.

Man kann natürlich hardwaremäßig kleinere Rechner mit festverdrahteter Logik darstellen und aufbauen. Das wird aber schnell unübersichtlich - speziell wenn das Ganze mehr als 1 Bit parallel bearbeiten soll.
Frag' doch mal bei INTeL nach - vielleicht rücken die ja Schaltpläne für den 8080 raus

Gruß

Dietmar Brüggendiek
Dietmar Brüggendiek
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
679 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Wie funzt der Assembler?

  Alt 20. Jan 2004, 14:16
Zitat von Alex_ITA01:
ADD:
klar sagt der Name schon das addiert eben zwei register miteinander aber irgendwie weiß ich nicht mehr recht wo der ganzzahlige anteil und der rest hinfällt (lässt sich aber einfach per debugger herausfinden)

ich kann dir ja gerne mal die liste mitbringen wenn du sie magst
hoffe das hier oben reicht erstmal ein stück für dich
mfg alex
bei Add wird zum 1. Register der Inhalt des Registers addiert, welches beim add-Befehl an 2. Stelle angegeben wird. Der Überschlag wird ins entsprechnde Gegen-Register gelegt. AX und DX bilden ein sogenanntes Registerpaar. CX und DX bilden auch eins, wenn ich mich recht entsinne.
Bsp:

mov ax, 0fffeh
mov bx, 3
add ax, bx
jo @@Overflow
;hier irgendwas machen, wenn es kein overflow gab
@@overflow:
;hier was machen, weil es den overflow gab

Danach steht in ax der wert 1 und in DX auch. Hört sich verwirrend, ist es aber ned. Testen kannst Du, ob es ein Überschlag gab, indem Du Dirdie Flags anschaust. Da Gibt es nämlich das OF (Overflow-Flag). Das wird dann gesetzt, wenn die letzte Operation einen Überlauf ergab. Bedingt springen kannst Du demnach mit dem Befehl "jo". Der Gegenbefehl dazu ist "jno" (Jump if No Overflow).

Bei mul sieht man das mit dem Overflow besonders gut.
Bsp.:

mov bx, 5
mov ax, 0ffffh
mul bx

in DX steht danach, wieoft AX einen overflow hatte.

ansonsten mußt Du insgesamt präzisere Fragen dazu stellen.

LG, MyRealName
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#5

Re: Wie funzt der Assembler?

  Alt 20. Jan 2004, 15:03
Ich empfehle Dir auf der Intel Homepage die CPU Dokumentationen zu downloaden. In diesen wird auch der Befehlssatz und somit der Assemblerpart erklärt. Im Gegensatz zur falschen Ausssage von "Realname" wirst du dort nachlesen können wie ADD korrekt funktioniert.

@RealName: Du verwechselst da was mit dem DIV + MUL Opcode.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
679 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Wie funzt der Assembler?

  Alt 20. Jan 2004, 15:26
@negaH: Stimmt, hab grad in Uralt-Sourcen nachgesehen, wie ich damals sowas programmiert hab (ist ja schon 8 Jahre her, daß ich exzessiv asm nutzte)

Hier ein Bsp. aus der damaligen Zeit, welches ADD und MUL demonstriert.

Code:
procedure PutPixel(_X,_Y : Word; _C : Byte);
var X, Y : Word;
    C, W : Byte;
begin
 X := _X; Y := _Y; C := _C; W := 0;
 asm
  pusha
  mov ax, 0a000h
  mov es, ax
  mov ax, 640d
  mul Y
  mov Byte Ptr [W], dl
  add ax, X
  jnc @@NoOverflow
   inc Byte Ptr [W]
  @@NoOverFlow:
  mov di, ax
  xor dx, dx
  mov dl, Byte Ptr [W]
  xor bx, bx
  mov ax, 04f05h
  int 10h
  mov al, Byte Ptr [C]
  stosb
  popa
 end;
end;
Eine Routine, die ein Pixel (im 256 FarbModus) an eine bestimmte Stelle eines SVGA-Screens (640x480) schreibt (VESA-Mode).

LG, MRN
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz