Hallo, guten Tag. Ich habe hier ein Programm gefunden für shl. --------------------------- org 100h start: mov bx,sp mov si,[bx+4] ; Zeiger auf die ZWEITE Variable nach SI mov cx,[si] ; 2. Variable in CX holen mov si,[bx+6] ; Zeiger auf die ERSTE Variable nach SI mov ax,[si] ; 1. Variable in AX holen mov bx,ax ; 1. Variable nach BX kopieren and bx,8000h ; Vorzeichen (Bit 15) isolieren, steht in BX shl ax,cl ; hier wird geschoben! and ax,7FFFh ; 15. Bit loeschen (Vorzeichen) or ax,bx ; und altes Vorzeichen wiederherstellen mov [si],ax ; Ergebnis in 1. Variable schreiben retf 4 ; Ruecksprung-Unterprogramm verlassen ---------------- Wie sieht bitte das Programm für shr aus. Oder geht es oben noch anders? Danke.
Oh Gott - einen Tag ohne eine saudämliche Frage von Peter B.Löd - sowas gibts nicht! lmgt fy.com/?q=8086+shr
das sind atomare Assembler-Befehle. logisches shift schiebt durch carry-bit raus und shiftet ne 0 rein arithmetisches shift beachtet das obere sign-bit. rotate schiebt rund durchs carry. http://www.c-jump.com/CIS77/ASM/Assembly/A77_0380_shl_shr.htm das shl ax,cl ist ein Multishift mit Anzahl in cl mov cl,16 shl ax,cl ist ein aufwendigeres und zeitraubenderes clear ax
:
Bearbeitet durch User
xor ax,ax braucht nur ein einziges Byte wenn ich mich recht erinnere.
Warum ist denn meins oben so kompliziert? Ich brauche nicht die Zahlenwerte minus oder plus. Ich brauche immer nur das 1. Byte vom Integerwert ob rechts oder links schieben. Das wird dann verarbeitet. Also wird da oben bei mir durch den ganzen Integerwert geschoben? Das kannte ich gar nicht. Ich dachte das geht nur über 1 Byte. Danke. Gruss
:
Bearbeitet durch User
Hä? Was brauchst Du? Du weißt, daß sich AX problemlos in AH und AL zerlegen lässt, je nachdem welches Byte Du brauchst? AX hat zwei Byte, AH ist das höherwertige Byte und AL das niedrige.
das Bespiel ist so komliziert weil die Vars über den Stack übergeben werden, weil es eine far function ist und die vars signed. Wenn du ein byte schieben willst nimm halt byte befehle. Schieben bei signed typen ist immer mit Vorsicht zu geniesen. Ich bin mir sicher das der Code ursprünglich von einem Compiler stammt. Niemand würde sowas programmieren.
Der 8086 sieht mir sehr ungeeignet aus für Low-Level-Programmierung, da zu komplex! Ist der damals vielleicht schon mit Blick auf Hochsprachen mit anschliessender Optimierung entwickelt worden ? Natürlich könnte man händisch assemblieren wenn etwas besonders schnell sein müsste.
> Ich bin mir sicher das der Code ursprünglich von einem Compiler stammt. Das war eine gängige Praxis, wenn man keine eigene gute Idee für eine Assembler-Lösung hatte. Dann wurde das mal schnell in C oder so hingeklatscht und geschaut wie der Compiler das Problem löst, ggf. wurde der Disassembler-Schnipsel dann mal eben in den eigenen Quelltext reingeguttenbergt. > Niemand würde sowas programmieren. Doch, die Variablen auf dem Stack übergeben hat einige Vorteile, vor allem wenn man Funktionen rekursiv verwenden möchte. Die maximale Tiefe wird dann nur von der maximalen Stackgröße bestimmt. > Der 8086 sieht mir sehr ungeeignet aus für Low-Level-Programmierung, > da zu komplex! So ein Quatsch. Der ist doch nicht komplex. Außerdem sind komplexe Befehle und Funktionen für die Assembler-Programmierung eher gut, weil man sich nicht so viel selbst zusammenstricken braucht wenn der Prozessor das in Hardware kann. Ich bin bei den Mikrocontrollern z.B. von den PICs zu den AVRs gewechselt, aus genau diesem Grund. Die PICs hatte ich zuerst in den Fingern und hab deswegen mit denen angefangen mich in das Thema einzuarbeiten. Aber deren minimalistische Ausstattung mit Assembler-Befehlen nervt. Ich glaube die hatten nicht mal einen echten Registersatz, sondern nur einen Akkumulator und das wars. Die Dinger sind viel eher für eine Hochsprache entwickelt, die wesentlich komplexeren AVRs lassen sich viel einfacher in Assembler programmieren.
> nicht mal einen echten Registersatz, sondern nur einen Akkumulator Da gibt es welche, die sind so beschraenkt, dass sie selbst die einfache Architektur nicht begreifen. Vermutlich begreift er den AVR auch nicht und stuempert lieber in C herum. Das was wie ein Akkumulator aussieht, ist nur ein Operandenhilfsregister. Und das was nicht wie echte Register aussieht, sind Akkumulatoren. Davon gibt es genau so viele wie es Register gibt. Und viel hin- und herspeichern muss man deswegen auch nicht. Was im jeweiligen Akkumulator/Register ausgerechnet wurde, kann dort einfach liegen bleiben...
Ben B. schrieb: >> Niemand würde sowas programmieren. > Doch, die Variablen auf dem Stack übergeben hat einige Vorteile, vor > allem wenn man Funktionen rekursiv verwenden möchte. Die maximale Tiefe > wird dann nur von der maximalen Stackgröße bestimmt. das ist bekannt und auch üblch das weis ich schon. schau noch mal genau hin: da wird was auf dem stack übergeben und verwurstelt und dann das Ergebnis auf dem Stack zurückgegeben soweit noch ok. ABER dann wird mit RETF 4 der stack abgebaut. Also entweder überseh ich gerade was oder das Ergebnis ist weg. Das ist entweder besonders clever oder aber grober Unsinn. Kanns leider nicht durchsteppen. Wie immer zeigt der TO ein Fragment total aus dem Kontext gerissen. Dazu passt auch das org 100. was wohl nur bei com Programmen anzutreffen ist. Edit: ich seh gerade das Ergebnis ist ja auch in AX ok dann gibt es doch einen Rückgabewert dann ist der letzte MOV vor dem RETF unnötig.
:
Bearbeitet durch User
Wenns danach geht, hat der Code so einige Sachen, die schwer verständlich sind. CX z.B. wird mit 16 Bit geladen, aber nur die unteren 8 Bit verwendet. Das Ergebnis zurückzuspeichern könnte dagegen recht sinnvoll sein, wenn der Programmdurchlauf eine Tabelle modifizieren soll oder was auch immer. Das geht aus dem kurzen Schnipsel nicht hervor. Der Programmanfang ist in der Form sowieso Schrott, das ORG 100h gehört zwar zu .COM-Dateien und man könnte das so assemblieren, allerdings arbeitet man dann mit einem uninitialisierten Stack oder Stackpointer. Der Schuss geht also an eine ziemlich beliebige Stelle im eigenen Segment und spätestens nach dem RETF schmiert die Kiste ab. Da fehlt definitiv der Programmteil, der diese Funktion aufruft. RETF ist auch untypisch für .COM-Programme, da diese mit DOS-Bordmitteln nur aus 64k-100h Bytes Code bestehen können und dafür braucht man keine far calls. Bei mehr Code (was schon ein verdammt großes Assemblerprogramm ist) nimmt man entweder .EXE-Dateien oder man muß einen eigenen Loader schreiben, um den Code nachzuladen. Ich weiß nicht mehr so extrem genau wie DOS .COM-Dateien lädt. Wahrscheinlich wird das komplette 64K-Segment an Speicher zugewiesen und der Stackpointer mit 0FFFFh initialisiert.
Hmm schrieb: > Der 8086 sieht mir sehr ungeeignet aus für Low-Level-Programmierung, da > zu komplex! > > Ist der damals vielleicht schon mit Blick auf Hochsprachen mit > anschliessender Optimierung entwickelt worden ? Natürlich könnte man > händisch assemblieren wenn etwas besonders schnell sein müsste. Der 8086 war mit Blick darauf entwickelt worden, dass man sehr einfach und ohne manuelle Arbeit Code für den 8085 auf diesen portieren kann, der wiederum zum 8080 kompatibel war und der wiederum zum 8008, welcher Anfang der Siebziger auf den Markt kam und damals sicherlich so gut wie ausschließlich in Assembler programmiert wurde.
:
Bearbeitet durch User
Ben B. schrieb: > RETF ist auch > untypisch für .COM-Programme, da diese mit DOS-Bordmitteln nur aus > 64k-100h Bytes Code bestehen können und dafür braucht man keine far > calls. Das sieht wirklich etwas merkwürdig aus, weil normalerweise Hochsprachen (C, Pascal z.B.) das mit der Stackübergabe so handhaben, um (für ein schnelles Rechenprogramm, einen bestimmten Hardwarezugriff o.ä.) auf die Assemblerebene zu gehen. Diese machen aber (vermutlich) Retf, weil (Segmentmanagement) schon fortschrittlich intus habend - der tatsächlich nicht in so ein kleines Unterprogramm gehört, außer eben als Hochsprachen-Assemblerunterteil. Selbst sollte man auch die Finger von so einem Befehl lassen, wenn man nicht genau weiß, was dahinter steckt. Was bleibt, sind Schablonen der Hochsprachenpraxis (wie mache ich ein Assembler-Unterprogramm in Sprache x) - Da kann man sich hier zumindest über den fehlenden Hinweis beschweren, diese Übergaben sind nicht einheitlich. Letztlich: Das stiftet hier nur unnötig Verwirrung. In dem Buch Digitaltechnik von Klaus Beuth ist noch ein 4-Bit Intel-cpu beschrieben (ob die neue aktuelle Ausgabe das auch noch macht, weiß ich nicht). Die Schaltungen werden sehr kompliziert bzw. die Segment-Lösung für 20Bit-Anpassung beim 8086 ist recht schwierig. Die Programmierung selber in Assember bzw. Hex (z.B. 7C für JL oder 5A für Pushall usw. ist aber sehr gut gemacht und macht viel Spaß. Gerade auch wegen dem einfachen .com-Format im Dos. Das beste an der Geschichte ist, dass man im Virtual-Mode die aktuellen Features der Intelcpus nutzen kann. Wie weit das heute geht, weiß ich nicht - weil der Virtual-Modus für Dos-Programme/bzw. 16Bit-Programme bei 64Bit nicht mehr geht. Man müsste zumindest ein 32Bit Windows zum Testen nehmen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.