11

私はこれに何週間も立ち往生していて、NASMが私にエラーを与えていないので、どこが間違っているのかわかりません。コメントがあるため、コードはかなり自明です。

これはBIOSからロードされるコードです

 ;--------------------------------------------
 ; '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

これは、ロードする必要がある(ただしロードしない)コードです。

 ;--------------------------------------------
 ; '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

どんな助けでも大歓迎です。

パトリック

4

5 に答える 5

7

jmp [es:bx]アドレスにジャンプしませんes:bx。このコマンドは、のワードに格納されているアドレスにニアジャンプしますes:bx。これが、多くの古いアセンブラがあなたにこの種の命令を次のように綴らせた理由jmp word ptr [es:bx]ですjmp near ptr [es:bx]。このようにして、何が起こるかがより明確になります。ここでおそらく必要なのは、固定された場所へのジャンプです。

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

にジャンプしたい場合は、以下es:bxを使用してretfください。

push es
push bx
retf
于 2009-10-13T10:23:08.773 に答える
2

コードで何を達成しようとしているのかわかりませんが、正しく理解している場合は、ディスクから0x8000の場所にいくつかのセクターを読み取り、そのコードを実行しますか?

その場合は、その特定の場所に明示的にCALL/JUMPを実行する必要があります。BIOSはそのコードを呼び出しません。起動時に、BIOSが初期化されると、命令ポインタIPがアドレス0x7c00に設定されます。その後、CPUはコードの実行を順番に開始するため、0x8000へのJMP / CALLがないと、0x7c00から0x8000の間などのすべてのメモリアドレスを実行するまで、0x8000でコードを実行しません。

したがって、解決策は、jcreaddiskの後にjmpまたはcall命令を設定することです。

私の理解が正しくない場合は、お詫び申し上げます。お役に立てれば。

于 2009-10-11T18:34:04.470 に答える
2

INT13の落とし穴の1つは、ヘッド番号とトラック番号が0から始まるのに、何らかの理由でセクター番号が1から始まることです。セクター書き込みユーティリティがこの番号付けスキームに準拠していることを確認できます。

質問:

  • 起動するとドットがいくつ見えますか?
  • フロッピーモーターは作動しますか?
于 2009-10-13T10:16:48.910 に答える
1

フロッピーを使用してOSを起動しているかどうかはわかりませんが、使用している場合は、ORGとビットの宣言の後にいくつかのことを宣言することをお勧めします(これらは非常に重要です)。

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
; ------------------------------------------------------------------

これを置くのは良い考えです。

よろしく。

于 2009-10-12T11:34:49.453 に答える
0

環境全体(ディスク、メモリダンプなど)をチェックできないため、コードが機能しない理由がわかりません...しかし、私が言えるのは...コードが間違っているということです。2番目のプログラムをロードしているのは0x8000(それが正しい使用のポイントでした0rg 0x8000か?)ではなく、0x80000です。

その理由は、segment:offsetアドレス指定を間違った方法で使用しているため、セグメント値が4ビット左にシフトされてからオフセットに追加されるため、アドレス0x8000:0x0000は線形アドレスに解決されます。0x80000

この問題を解決するには、メモリダンプを調べて、プログラムが期待どおりに機能するかどうかを確認する必要があります。それか、ディスクの間違ったセクターをロードしています。

于 2011-04-30T16:53:46.440 に答える