Frage

Ich habe jetzt seit Wochen mit diesem stecken und keine Ahnung, wo ich falsch werde, weil NASM mir keine Fehler gegeben hat. Der Code ist ziemlich selbsterklärend, weil die Kommentare.

Dies ist der Code, der vom BIOS

geladen wird
 ;--------------------------------------------
 ; 'boot.asm'
 ; loaded from BIOS

 [org 0x7C00]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

 resetdisk:
  mov ah, 0x00  ; reset function
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc resetdisk

 readdisk:
  mov bx, 0x8000  ; segment
  mov es, bx
  mov bx, 0x0000  ; offset

  mov ah, 0x02  ; read function
  mov al, 0x03  ; sectors
  mov ch, 0x00  ; cylinder
  mov cl, 0x02  ; sector
  mov dh, 0x00  ; head
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc readdisk
  jmp [es:bx]   ; buffer

 ;--------------------------------------------

 times 510 - ($ - $$) db 0x00
 db 0x55, 0xAA

Dies ist der Code, der sein soll (aber nicht) geladen

 ;--------------------------------------------
 ; 'load.asm'
 ; loaded from 'boot.asm'

 [org 0x8000]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

  jmp $    ; hang

Alle Hilfe sehr geschätzt wird.

Patrick

War es hilfreich?

Lösung

jmp [es:bx] springt nicht an die Adresse es:bx. Dieser Befehl führt einen in der Nähe von Sprung zu der Adresse im Wort bei es:bx gespeichert. Aus diesem Grund viele ältere Montierer gemacht Sie diese Art von Unterricht als jmp word ptr [es:bx] oder sogar jmp near ptr [es:bx] buchstabieren; es ist klarer auf diese Weise, was passieren wird. Was Sie wahrscheinlich hier wollen, ist ein weit Sprung zu einem festen Standort:

; jmp far 8000:0000
db 0eah
dw 00000h ; offset
dw 08000h ; segment

Wenn Sie nicht möchten, um es:bx zu springen, Verwendung retf:

push es
push bx
retf

Andere Tipps

Ich bin nicht sicher, was Sie versuchen, mit dem Code zu erreichen, aber wenn ich es richtig verstehen, Sie wollen ein paar Sektoren von der Platte in die Lage 0x8000 zu lesen und dann diesen Code ausführen?

Wenn das der Fall ist, dann werden Sie explictly einen CALL / JUMP zu diesem bestimmten Ort zu machen. Das BIOS wird nicht, dass Code für Sie anrufen. Beim Booten, sobald die BIOS initialisiert wird, wird es die Befehlszeiger IP an die Adresse 0x7c00 gesetzt. Die CPU wird dann starten Sie den Code sequentiell, also ohne JMP / CALL 0x8000 auszuführen es den Code 0x8000 ausführen würde nicht, bis er jede Speicheradresse zwischen 0x7c00 zu 0x8000 etc ausgeführt hat.

So ist die Lösung eine JMP oder Call-Befehl nach dem jc readdisk zu haben wäre.

Wenn mein Verständnis falsch ist, dann entschuldige ich mich. Hoffe, das hilft.

Ein Gotcha mit INT13 ist, dass Kopf und Titelnummern beginnen bei 0, aber Sektornummern aus irgendeinem Grunde beginnt bei 1. Das könnten Sie überprüfen, ob Ihr Sektor-Schreiben Dienstprogramm Konform dieses Nummerierungsschema.

Fragen:

  • Wie viele Punkte sehen Sie, wenn Sie starten?
  • Ist der Diskette Motor Kick auf?

Ich weiß nicht, ob Sie eine Diskette verwenden Sie das Betriebssystem zu booten, aber wenn Sie verwenden, empfehle ich Ihnen einige Dinge nach der ORG und Bits Erklärung zu erklären, werfen Sie einen Blick (sie sehr wichtig sind):

JMP short main   ; Jump past disk description section
NOP              ; Pad out before disk description

; ------------------------------------------------------------------
; Disk description table, to make it a valid floppy
; Note: some of these values are hard-coded in the source!
; Values are those used by IBM for 1.44 MB, 3.5 diskette

OEMLabel            db "BERL OS"    ; Disk label - 8 chars
BytesPerSector      dw 512          ; Bytes per sector
SectorsPerCluster   db 1            ; Sectors per cluster
ReservedForBoot     dw 1            ; Reserved sectors for boot record
NumberOfFats        db 2            ; Number of copies of the FAT
RootDirEntries      dw 224          ; Number of entries in root dir
LogicalSectors      dw 2880         ; Number of logical sectors
MediumByte          db 0F0h         ; Medium descriptor byte
SectorsPerFat       dw 9            ; Sectors per FAT
SectorsPerTrack     dw 18           ; Sectors per track (36/cylinder)
Sides               dw 2            ; Number of sides/heads
HiddenSectors       dd 0            ; Number of hidden sectors
LargeSectors        dd 0            ; Number of LBA sectors
DriveNo             dw 0            ; Drive No: 0
Signature           db 41           ; Drive signature: 41 for floppy
VolumeID            dd 00000000h    ; Volume ID: any number
VolumeLabel         db "BERL OS"    ; Volume Label: any 11 chars
FileSystem          db "FAT12"      ; File system type: don't change!

; End of the disk description table
; ------------------------------------------------------------------

Es ist eine gute Idee, dies zu setzen.

Viele Grüße.

Ich bin mir nicht sicher, warum der Code nicht funktioniert, da ich nicht das die gesamte Umgebung überprüfen (Laufwerke, Speicherabbild, usw.) ... aber was ich sagen kann ist ... ist der Code falsch . Sie sind das zweite Programm, nicht auf 0x8000 Laden (dass der Punkt der Verwendung 0rg 0x8000 richtig war?), Aber bei 0x80000.

Der Grund dafür ist, Sie sind mit dem Segment: Versatz in der falschen Art und Weise Adressierung, die Adresse 0x8000:0x0000 wird auf die lineare Adresse 0x80000 aufgelöst, da der Segmentwert um 4 Bits nach links verschoben, dann ein auf den Offset hinzugefügt.

Um dieses Problem zu beheben, sollten Sie einen Blick auf einem Speicherabbild und sehen, ob das Programm funktioniert, wie Sie es zu erwarten .... entweder das, oder du bist Laden der falsche Sektoren der Festplatte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top