Ausgabe von Hexzahlen
-
man kann sich sowas gut im Debugger anschauen, gerade das macht Assemblerroutinen so sympathisch.
Da in den Registern sowieso nur Werte von 0-F stehen, reicht eine Fallunterscheidung, cmp al,09 jle über den Buchstabenaddierer hinweg
man könnte den Registerinhalt aller register (auch xmms) in den Speicher kopieren:
mov [200],eax
usw.und dann mit lodsb(+registerbreite in cl) den Speicher byteweise in al hineinlesen. der vorteil wäre vielleicht, die gleiche routine - nur mit Längenanpassung für xmm-Register zu benutzen -, die ja sowieso in den Speicher schreiben müssen. Und Al als ArbeitsundAusgaberegistebasis ist eher bioskompatibel als die anderen und hier und da auch besser beschleunigt . Aber es ist fast egal, wie mans macht, nur hier in diesem Beispiel wird der Code durch die Buchstabenliste unnötig unübersichtlich.
Wenn man den geposteten code selbst mal etwas genauer anschaut:
push ebx ;is ja das Arbeitsregister, also sichern mov dword [addi1],edx ;warum nicht push edx? xor ebx,ebx ;nicht nötig, wird sowieso überschrieben xor ecx,ecx ;ecx = 0, gut, denn cl wird überschrieben, ch aber nicht mov edx,[addi1] ;warum jetzt nicht nicht pop edx? aber wozu? der alte ;Wert steht ja noch in edx
man braucht cx nicht unbedingt, aber wenn schon im Gebrauch, dann könnte der Routineanfang so aussehen: push ecx, push edx, push ebx
sal edx,cl ;arithmeitscher Linksshift - aber in cl steht 0, ;also wozu? sar 28 ;vorher edx=F000 0000, nacher edx=0000 000F, bzw.1000000F mov bl,dl ;bl = 0F
für diesen Fall würde ein
add bl,30 cmp bl,39 jle zum Printer add bl 07 print-Int oder call print-int ret
genügen
wenn in bl nun aber FF steht, dann muss man gucken, wie man das F vor dem F wegbekommt...äh...ach nein, wie man das F hinter dem F vor dem F weg bekomt...;)
-
Erstmal danke für die Antworten.
Ich überarbeite gerade die Routine sie sieht gerade so aus:
;print_hex ;edx=the hexnumber of edx is printed on the screen global print_hex print_hex: push ebx push ax mov dword[eedx],edx;save edx xor ebx,ebx; set ebx to zero so that I just can use bl ;get Hexcode in ASCII Format xor ecx,ecx get_hex.loop: mov edx,dword[eedx] sal edx,cl sar edx,28 mov bl,dl call get_hex ;print Number on the screen mov ax,0x0100 int 0x31;call darkblack Function "printchar" add ecx,4 cmp ecx,32 jnz get_hex.loop pop ax pop ebx ret print_hex.data: eedx dd 0 print_hex.function: get_hex: cmp bl,0x09 ja get_hex.ifABCDEF ;if bl is a number not a char add bl,0x30 jmp get_hex.end get_hex.ifABCDEF: add bl,0x41 get_hex.end: ret
Und vielleicht sollte ich sagen, dass ich an meinem eigenem OS arbeite, daher gibt es noch nicht so viele Funktionen auf die ich zurückgreifen könnte.
-
Scheint nicht ganz angekommen zu sein, worauf ich hinaus wollte:
get_hex.loop: mov edx,dword[eedx] sal edx,cl sar edx,28 mov bl,dl call get_hex ;print Number on the screen ;... add ecx,4 cmp ecx,32 jnz get_hex.loop
Ist nicht so gut.
Zudem duerfte dein Fehler in der sinnlosen Verwendung von arithmetischen statt Bitoperationen liegen.Ich wuerde vorschlagen, du machst entweder die Verarbeitung der Ziffern byteweise wie nachtfeuer vorschlaegt, oder zumindest sinnvoller mit Rotationen und Und-Verknuepfung.
zB.
Rotiere am Anfang jeder Schleife edx um 4 nach links (rol).
Kopier edx nach ebx und isoliere die untersten 4 Bit mit Und-Verknuepfung. Das machst du 8 mal, dann steht als netter Nebeneffekt in edx hinterher wieder das Gleiche wie am Anfang.
Die paar Zeilen fuer das Errechnen einer einzelnen Ziffer in eine eigene Funktion zu packen ist uebrigens etwas uebertrieben und unnoetig ineffizient. Wenn du deinen Code uebersichtlicher machen willst, packst du solche kurzen Stuecke besser in Macros...
-
Ich habe die Funktion noch korrekt schreiben können.
Ich habe eine andere Möglichkeit benutzt, die wesentlich einfacher ist.
Ich habe einen Wert, der ausgegeben werden soll in EBP gespeichert und ihn immer durch 16 geteilt und der Rest, war dann die neue Hexziffer, die nur noch in einen passenden ASCII Code umgewandelt werden muss und ausgegeben werden kann.Ich kann nur hoffen, dass meine Beschreibung den Leuten hilft, die vielleicht das selbe Problem haben ;).
-
Auch eine Moeglichkeit...
Als Faustregel sollte man komplexe Operationen wie Multiplikationen und Divisionen allerdings eher meiden, wenn es einfachere Operationen auch tun.
-
Im IRC wurde mir der Typ gegeben und ich hoffe, das meine Beschreibung einigen hilft und mit der Faustregel Nobuo T hast du vollkommen recht, aber wenn man extrem viel machen muss um nur auf das selbe Ergebnis, wie eine komplexere Funktion zu kommen, würde ich diese direkt nutzen, aber das ist meine Meinung.
-
Etwas aehnliches wurde schon oft gefragt, aber ich bin einfach zu faul, das in einen sauberen FAQ-Eintrag zusammen zu fassen und es hat sich auch noch niemand anders dazu bereit erklaert.
Was meinst du mit "wenn man extrem viel machen muss"? Du als Programmierer? Warum programmierst du dann Assembler? Oder die CPU? Da musst du abwaegen: Je nach Modell und einigen anderen Umstaenden koennen oft selbst 3 simple Instruktionen effizienter sein als eine einzige komplexe Instruktion.
Sicher wird man idR. eine einzelne Multiplikations-Instruktion nehmen, um zB. das Produkt zweier Variablen zu berechnen. Gerade bei Rechnungen mit Konstanten, die dazu auch noch Integer-2er-Potenzen sind, sind extra Multiplikations- und Divisionsinstruktionen jedoch meistens Overkill.
Fuer die Umwandlung in einen Hex-String braeuchtest du bei halbwegs effizienten Implementierungen zB. nur eine simple Instruktion pro Schleifendurchlauf mehr, um den Algorithmus nur mit simplen Bitoperationen statt mit einer Divisionsinstruktion zu implementieren. In solchen Faellen haelt der besonnene Assembler-Programmierer kurz inne, und denkt noch einmal scharf darueber nach, ob eine Loesung, die ohne komplexen Opcodes auskommt, nicht vielleicht guenstiger ist.Gut, in diesem konkreten Fall ist das sicher ziemlich Wumpe, da dieser Code wohl kaum besondere Anforderungen zu erfuellen hat. Bei aktuellen PC-CPUs sollte man es eh vermeiden, all zu genau ueber Optimierungen nachzudenken, wenn man nicht gerade auf bestimmte Modelle spezialisierte, hoch optimierte Software schreibt... fuehrt sonst nur zu Frustration.
Mit og. Faustregel solltest du aber idR. auf der sicheren Seite sein.
-
Nobuo T schrieb:
Etwas aehnliches wurde schon oft gefragt, aber ich bin einfach zu faul, das in einen sauberen FAQ-Eintrag zusammen zu fassen und es hat sich auch noch niemand anders dazu bereit erklaert.
Was meinst du mit "wenn man extrem viel machen muss"? Du als Programmierer? Warum programmierst du dann Assembler? Oder die CPU? Da musst du abwaegen: Je nach Modell und einigen anderen Umstaenden koennen oft selbst 3 simple Instruktionen effizienter sein als eine einzige komplexe Instruktion.
es ist im übrigen auch nicht neues, wenn hier leute reinschreiben, die damit prahlen, ein eigenes betriebsystem zu schreiben, aber gleichzeitig durchscheinen lassen, dass ihre grundlagenkenntnisse in richtung null tendieren - und statt ihre eigenen routinen oder vorgehensweise zu debuggen(oder die antworten im forum auszuwerten), lieber in anderen foren nach aufmerksamkeit heischen.
man sieht es aber auch immer wieder in foren, die sich mit OS programming beschäftigen: nahezu null grundlagenverständnis, und die anleitung vom assembler gelesen schon gar nicht.
-
@schnelldurchreisender: Ich sehe es positiv, bin aber natürlich kein Pädagoge. Die Grundlagenkenntnisse kommen ja nicht von alleine und müssen irgendwie erarbeitet werden. Man stellt sich eine Aufgabe und versucht, die Aufgabe zu lösen. Das hat nichts mit "nach aufmerksamkeit heischen" zu tun.
-
Mh, naja. Ich wuerde dir normalerweise zustimmen, learning by doing ist eine feine Sache und ein Hobby-OS sicher ein gutes Studienprojekt. Fuer sowas legt man dann aber normalerweise nicht online ein Projekt an und wirbt dafuer in Foren Entwickler, vor allem offenbar ohne selbst ueber nennenswertes Grundlagenwissen und damit die Moeglichkeit zu verfuegen, selbst wirklich etwas erarbeiten zu koennen.
-
kommt ihr nicht irgendwie auf den Gedanken, dass man nicht alles perfekt kann?
und ihr müsst ja nicht mitmachen, wenn ihr nicht wolltund hier MEIN SELBER erarbeiteter Code
48 ;print_hex 49 ;ebp=the hexnumber of edx is printed on the screen 50 global print_hex 51 print_hex: 52 mov dh,8;times of the repitition of the loop 53 mov bh,0x10;16 is the base of hexadecimal system 54 rol ebp,4 55 print_hex.loop: 56 mov eax,ebp 57 xor ah,ah;if ah is not zero ax is to big 58 div bh 59 mov bl,ah 60 call get_hex 61 mov ax,0x0100;the printchar function of the darkblackAPI 62 int 0x31 63 rol ebp,4 64 dec dh 65 test dh,dh 66 jnz print_hex.loop 67 ret 68 print_hex.function: 69 get_hex: 70 cmp bl,0x0A 71 jae get_hex.ifABCDEF 72 ;if bl is a number not a char 73 add bl,0x30 74 jmp get_hex.end 75 76 get_hex.ifABCDEF: 77 add bl,0x37 78 79 get_hex.end: 80 ret
-
Damit der Quellcode perfekt wird, musst Du noch die unnötig leeren Zeilen löschen und nach dem Komma gehört ein Leerzeichen hin
Zum Beispiel, nicht
mov dh,8
sondern
mov dh, 8
-
tev schrieb:
kommt ihr nicht irgendwie auf den Gedanken, dass man nicht alles perfekt kann?
und ihr müsst ja nicht mitmachen, wenn ihr nicht wolltNiemand ist Perfekt, also keine Schande. Und keine Sorge, ich habe noch nicht einmal Zeit an Erhards OS-Projekt mitzuarbeiten, und der hat hier sogar sein eigenes Unterforum.
Allerdings, falls du es noch nicht bemerkt hast, sry dir das so deutlich sagen zu muessen: Du erweckst hier gerade etwas den Eindruck, in Sachen OS-Entwicklung deutlich naeher an gar nicht als an perfekt koennen zu sein. Bei dir mangelt es scheinbar noch selbst an grundlegendsten mathematischen und logischen Kniffen.
Es ist eine gute Idee, sich mit Anderen zum Lernen in einem Projekt zusammen zu tun. Dabei aber mit deinen Faehigkeiten so zu tun, als waerst du ein Foll-Provieh, ist etwas unfair...tev schrieb:
und hier MEIN SELBER erarbeiteter Code
... Naja, wie gesagt ...
Du solltest dich schon entscheiden: Willst du nun Bitoperationen oder die Divisionsoperation benutzen. Beides gleichzeitig ist hier nun wirklich unsinnig.
Tipp: x modulo 16 == x & 15
-
tev schrieb:
kommt ihr nicht irgendwie auf den Gedanken, dass man nicht alles perfekt kann?
und ihr müsst ja nicht mitmachen, wenn ihr nicht wolltund hier MEIN SELBER erarbeiteter Code
[asm ...
naja, es ist auch manchmal schwierig, wie man antwortet, die meisten hier kennen den spaß am selber ausknobeln, und den lerneffekt, also wo die grenze ziehen?
und hier eine alternative:
mov cl,8 wiederholungstäter: rol ebp,4 mov ebx,ebp and ebx,0000000f call ausgabe loop wiederholungstäter
du solltest aber unbedingt noch verstehen, warum deine voherige ausarbeitung, die so schlecht nicht war, den genannten ausgabefehler produzierte.
eine möglichkeit, verständnis zu gewinnen wäre, den wert 7fffffff nach eax und den wert 1 nach ebx zu laden und add eax,ebx zu machen und dabei zu schauen, was die flags anzeigen. und natürlich, was die beiden befehle shr und sar unterscheidet.Nobuo T schrieb:
... Naja, wie gesagt ...
Du solltest dich schon entscheiden: Willst du nun Bitoperationen oder die Divisionsoperation benutzen. Beides gleichzeitig ist hier nun wirklich unsinnig.
Tipp: x modulo 16 == x & 15...rein lerntechnisch vielleicht gar kein nachteil, man lernt ja beides - aber der begriff "Foll-Provieh" ist echt klasse *rotfl*
wir könnten durchaus etwas zur humorecke beitragen, in dem wir eine top-ten der abstrusesten behauptungen aufstellen.
Der vorgängerthread
http://www.c-plusplus.net/forum/viewtopic-var-t-is-274303-and-sid-is-78bcea662dbc6b77effc87cf427907a7.html
ist auch so ein kandidat...
-
Heh, welche abstrusen Behauptungen meinst du jetzt konkret?
Nichts gegen ein wenig Humor auf Kosten einiger Beteiligter, aber bei mir fuehrt sowas hier schon bald zu Fremdschaemen... und bei solcher Comedy gehe ich immer an die Decke, und zwar nicht vor Vergnuegen.
-
OK, dann tut es mir leid, dass es rüberkam, dass ich mich als Vollprofi sehe, was aber eigentlich nicht so ist
Ich hatte eigentlich nur nach ein paar Mitstreitern für mein OS gesucht
Dann sage ich es noch einmal, ich bin kein Vollprofi, aber ich schreibe trotzdem an meinem eigenen OS, auch wenn ich vielleicht öfters hängen bleibe als andere, weil ich eben kein Profi bin. Aber was nicht ist, kann ja noch werden :p
-
Nobuo T schrieb:
Heh, welche abstrusen Behauptungen meinst du jetzt konkret?
Nichts gegen ein wenig Humor auf Kosten einiger Beteiligter, aber bei mir fuehrt sowas hier schon bald zu Fremdschaemen... und bei solcher Comedy gehe ich immer an die Decke, und zwar nicht vor Vergnuegen.Na, ich bin auch nicht so der Freund von Beleidigungsrethorik oder Supertalentruntermache(im TV) o.ä. (Aber was ist Fremdschämen?)
Fassen wir uns also lieber erstmal an die eigene Nase, dieser Thread fängt schon spannend an:
Nobuo T schrieb:
Ich sehe da jetzt keinen gravierenden Fehler, der irgendein abweichendes Verhalten bei Ziffern > 7 ausloesen koennte (was genau passiert ueberhaupt?), aber: WTF?
oder
nachtfeuer schrieb:
sal edx,cl ;arithmeitscher Linksshift - aber in cl steht 0, ;also wozu? sar 28 ;vorher edx=F000 0000, nacher edx=0000 000F, bzw.1000000F mov bl,dl ;bl = 0F
wieder mal so halbschlafantworten...
abc.w schreibt gar nicht viel, rückt nicht mal ein paar unix-kennerschaftdebugginginsiderhints heraus, kann ich mir nur damit erklären, dass abc.w sich das monatskontingent für brauchbare antworten beim RC4 verschlüsselungsthread völlig aufgebraucht hat...:D
-
nachtfeuer schrieb:
abc.w schreibt gar nicht viel, rückt nicht mal ein paar unix-kennerschaftdebugginginsiderhints heraus, kann ich mir nur damit erklären, dass abc.w sich das monatskontingent für brauchbare antworten beim RC4 verschlüsselungsthread völlig aufgebraucht hat...:D
Nein, ich sehe halt keine "Herausforderung", ist zu "easy"