Frage zu Assembler
-
Hallo müsste Assembler nicht eigentlich Plattform Unabhängig sein sofern man den selben Prozessor benutzt ?
ür
Also z.b. mit:mov dx,offset var mov ah,9h int 21h
Könnte ich ja kein Text auf dem Bildschirm ausgeben Linux benutzt ja auch den z.b. den Interrupt int 0x80 oder so für Text ausgeben und natürich nicht mov ah,9h
weil das ja aus der MS DOS API stammt.Meine Frage ist jetzt wie kann z.b. einfach Text ausgeben auf Windows so wie auf Linux wenn die beiden Quelltexte gleich sein sollen oder geht das gar nicht ?
-
Also ich hab hier jetzt nochmal gelesen: http://en.wikibooks.org/wiki/X86_Assembly/X86_Interrupts
Hardware Interrupts Hardware interrupts are triggered by hardware devices. For instance, when you type on your keyboard, the keyboard triggers a hardware interrupt. The processor stops what it is doing, and executes the code that handles keyboard input (typically reading the key you pressed into a buffer in memory). Hardware interrupts are typically asynchronous - their occurrence is unrelated to the instructions being executed at the time they are raised. [edit] Software Interrupts There are also a series of software interrupts that are usually used to transfer control to a function in the operating system kernel. Software interrupts are triggered by the instruction int. For example, the instruction "int 14h" triggers interrupt 0x14. The processor then stops the current program, and jumps to the code to handle interrupt 14. When interrupt handling is complete, the processor returns flow to the original program.
Nur durch Hardware Interrupts kann man z.b. keine Text ausgeben oder ?
-
Ohje, ich muss dir leider sagen, dass deine Schreibe ziemlich schwer verstaendlich ist. Aber ich versuche mich mal:
x86 schrieb:
Hallo müsste Assembler nicht eigentlich Plattform Unabhängig sein sofern man den selben Prozessor benutzt ?
Nein. Warum das so ist, beantwortest du weiter unten selbst.
x86 schrieb:
Also z.b. mit:
mov dx,offset var mov ah,9h int 21h
Könnte ich ja kein Text auf dem Bildschirm ausgeben Linux benutzt ja auch den z.b. den Interrupt int 0x80 oder so für Text ausgeben und natürich nicht mov ah,9h
weil das ja aus der MS DOS API stammt.Wie du richtig bemerkst, ist int 21h, Funktion 9 in der DOS-API die Funktion zum Ausgeben eines Strings bei ds:dx auf stdout (idR. die Konsole, bzw. der "Bildschirm").
Windows oder Linux haben eine andere API in der jeweils andere Funktionsaufrufe zum Ausgeben von Text benutzt werden.x86 schrieb:
Meine Frage ist jetzt wie kann z.b. einfach Text ausgeben auf Windows so wie auf Linux wenn die beiden Quelltexte gleich sein sollen oder geht das gar nicht ?
Falls du mit "beiden Quelltexte gleich" tatsaechlich identische Quelltexte meinst: Funktioniert wegen der unterschiedlichen APIs nicht, siehe oben.
Falls du gleiche Funktionalitaet meinst: Klar geht das. Schliesslich ist der Sinn einer Konsole, darin Text ausgeben zu koennen.In Windows gibt es dafuer zB. die Funktion WriteConsole: (Pseudo-Assembler)
;... push NULL ; lpReserved push lpNumberOfCharsWritten push [len] ; Anzahl der Zeichen push msg ; Offset des Strings, der ausgegeben werden soll push [hConsoleOutput] ; console stdout handler call writeConsole ;...
oder in Linux int 80h, Funktion 4:
;... mov edx,[len] ; Anzahl der Zeichen mov ecx, msg ; Offset des Strings, der ausgegeben werden soll mov ebx, 1 ; stdout handler mov eax, 4 ; Funktion 4 = sys_write int 80h ; software interrupt 80h
x86 schrieb:
Nur durch Hardware Interrupts kann man z.b. keine Text ausgeben oder ?
Mach dir mal den Unterschied zwischen Hardware- und Software-Interrupt klar:
Wenn du in deinem Code den Befehl "int xy" verwendest, rufst du damit einen Software-Interrupt auf. Der Funktioniert im Prinzip aehnlich wie ein normaler Funktionsaufruf: Mit diesem Befehl springt die CPU zum Funktionscode des Interrupt und faehrt anschliessend mit der Ausfuehrung des naechsten Befehls hinter dem int fort.Ein Hardware-Interrupt wird, wie der Name schon andeutet, allein durch Hardware ausgeloest. Darauf hast du also keinen direkten Einfluss. IdR. signalisiert ein Geraet der CPU mit einem Hardware-Interrupt, dass ein Ereignis eingetreten ist, dass behandelt werden muss. z.B. loest der Tastaturcontroller einen Interrupt aus, wenn du eine Taste drueckst und dadurch neue Daten im Tastaturpuffer liegen, die abgeholt werden muessen, oder die Soundkarte loest einen Interrupt aus, weil sie einen Ton-Puffer fertig abgespielt hat und einen neuen Puffer zum Abspielen braucht, usw.
-
man könnte sich auch einen eigenen "interrupt" schreiben, der unterschiedliche z.B. addressierungsmodes zwar unterschiedlich verarbeitet, aber hier wie dort gleich heißt. bei den höheren programmiersprachen erfüllt einen ähnlichen zweck sogenannt runtime, bibliothek, header usw. der große vorteil ist die standardisierung.
x86-assemblersystemsubroutinen sind leider nicht standardisiert,
Sowas ließe sich aber nachholenmit etwas glück, den richtigen leuten, einem überdurchschnittlich leistungsfähigen wie einsteigerfreundlichem tool wie fasm und einem freundlicher 64bit addressierungsmodes und vielen lowlevelfreaks könnte das gelingen...*träum*:)
zumindest auf der bios-ebene besteht eine gewisse plattformunabhängigkeit. das wird auch in zukunft so sein, die nachfolge-biosse sind dann vermutlich
open-source geschichten wie
http://www.coreboot.org/Welcome_to_coreboot
http://www.heise.de/open/artikel/Zehn-Jahre-LinuxBIOS-Coreboot-221667.html
und vielleicht hat bis dahin auch jemand oder viele andere Ralf Browns interruptliste nach Linux heute übersetzt...;)
-
Libs benutzt man allgemein (in Hochsprachen wie in Assembler) zur Kapselung und Abstraktion. Indem du dein Programm mit an verschiedene Plattformen und Systeme angepassten Libs erstellst, die von ihrem intern natuerlich stark system- und plattformabhaengigen Code abstrahieren, laesst sich in Hochsprachen relativ plattformunabhaengiger Code schreiben.
In Assembler kannst du natuerlich auch Libs (nichts haelt dich davon ab, ein Programm zu schreiben, das z.B. eine c std-lib benutzt) oder Funktionen verwenden und somit ein Stueck weit von der System-API abstrahieren und systemunabhaengig programmieren.
Diese Kapselung ueber die Einrichtung eines neuen Interrupts zu erreichen ist aber keine gute Idee, da Interrupt-Aufrufe langsam sind und bereits die Installation von Interrupthandlern systemspezifisch ist (ich weiss zB. nicht, wie/ob das in Windows ueberhaupt geht).
Zumindest die Plattformabhaengigkeit (CPU und evtl. auch deren Betriebsmodus - zB. auf x86) wirst du dagegen niemals ganz los. Dafuer gibt es Hochsprachen, die davon abstrahieren.Also kein Grund, das Rad neu zu erfinden.
Von daher muss ich mich also korrigieren: mit Funktionen wie printf ist es schon moeglich, fuer Aufgaben wie Ausgabe in Konsolen exakt gleichen Code fuer verschiedene Betriebssysteme zu verwenden. Voraussetzung ist die Plattformkompatibilitaet.
-
Hallo eine Frage habe ich noch.
Was ist das denn dann hier für Assembler das ist ja weder die DOS API noch die Linux API was wird hier verwendet.
Den Quelltext habe ich von: http://wiki.osdev.org/Real_mode_assembly_I
( Nein ich will keine Betriebssystem programmieren ^^ mich interessiert einfach nur was das für ein Assembler ist )
mov ax, 0x07C0 ; set up segments mov ds, ax mov es, ax mov si, welcome call print_string loop: mov si, prompt call print_string mov di, buffer call get_string mov si, buffer cmp byte [si], 0 ; blank line? je loop ; yes, ignore it mov si, buffer mov di, cmd_hi ; "hi" command call strcmp jc .helloworld mov si, buffer mov di, cmd_help ; "help" command call strcmp jc .help mov si,badcommand call print_string jmp loop .helloworld: mov si, msg_helloworld call print_string jmp loop .help: mov si, msg_help call print_string jmp loop welcome db 'Welcome to My OS!', 0x0D, 0x0A, 0 msg_helloworld db 'Hello OSDev World!', 0x0D, 0x0A, 0 badcommand db 'Bad command entered.', 0x0D, 0x0A, 0 prompt db '>', 0 cmd_hi db 'hi', 0 cmd_help db 'help', 0 msg_help db 'My OS: Commands: hi, help', 0x0D, 0x0A, 0 buffer times 64 db 0 ; ================ ; calls start here ; ================ print_string: lodsb ; grab a byte from SI or al, al ; logical or AL by itself jz .done ; if the result is zero, get out mov ah, 0x0E int 0x10 ; otherwise, print out the character! jmp print_string .done: ret get_string: xor cl, cl .loop: mov ah, 0 int 0x16 ; wait for keypress cmp al, 0x08 ; backspace pressed? je .backspace ; yes, handle it cmp al, 0x0D ; enter pressed? je .done ; yes, we're done cmp cl, 0x3F ; 63 chars inputted? je .loop ; yes, only let in backspace and enter mov ah, 0x0E int 0x10 ; print out character stosb ; put character in buffer inc cl jmp .loop .backspace: cmp cl, 0 ; beginning of string? je .loop ; yes, ignore the key dec di mov byte [di], 0 ; delete character dec cl ; decrement counter as well mov ah, 0x0E mov al, 0x08 int 10h ; backspace on the screen mov al, ' ' int 10h ; blank character out mov al, 0x08 int 10h ; backspace again jmp .loop ; go to the main loop .done: mov al, 0 ; null terminator stosb mov ah, 0x0E mov al, 0x0D int 0x10 mov al, 0x0A int 0x10 ; newline ret strcmp: .loop: mov al, [si] ; grab a byte from SI mov bl, [di] ; grab a byte from DI cmp al, bl ; are they equal? jne .notequal ; nope, we're done. cmp al, 0 ; are both bytes (they were equal before) null? je .done ; yes, we're done. inc di ; increment DI inc si ; increment SI jmp .loop ; loop! .notequal: clc ; not equal, clear the carry flag ret .done: stc ; equal, set the carry flag ret times 510-($-$$) db 0 db 0x55 db 0xAA
-
Was meinst du mit "Was ist das denn dann hier für Assembler"?
Die "Meta-Syntax" ist fuer NASM, steht auch im Artikel.
Und logischerweise stehen ohne das jeweilige OS deren APIs auch nicht zur Verfuegung. Deshalb benutzt dieser Code fuer Hardware-E/A BIOS-Funktionen. Das ist neben EFI auf neuen PCs oder evtl. ueber Firmware auf Hardware installierten Funktionen die einzige "API", die bei der OS-Entwicklung zunaechst verfuegbar ist.
-
Damit hat sich meine Frage glaube ich schon beantwortet danke.
Und logischerweise stehen ohne das jeweilige OS deren APIs auch nicht zur Verfuegung. Deshalb benutzt dieser Code fuer Hardware-E/A BIOS-Funktionen. Das ist neben EFI auf neuen PCs oder evtl. ueber Firmware auf Hardware installierten Funktionen die einzige "API", die bei der OS-Entwicklung zunaechst verfuegbar ist.