How to load a kernel from disk with BIOS int 13h in NASM assembly?

前端 未结 5 2030
醉话见心
醉话见心 2021-02-02 01:21

I\'ve been stuck with this for weeks now and have no idea where I\'m going wrong because NASM hasn\'t given me any errors. The code is pretty self explanatory because of the com

相关标签:
5条回答
  • 2021-02-02 01:55

    jmp [es:bx] doesn't jump to the address es:bx. This command does a near jump to the address stored in the word at es:bx. This is why lots of older assemblers made you spell this kind of instruction as jmp word ptr [es:bx] or even jmp near ptr [es:bx]; it's clearer this way what is going to happen. What you probably want here is a far jump to a fixed location:

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

    If you do want to jump to es:bx, use retf:

    push es
    push bx
    retf
    
    0 讨论(0)
  • 2021-02-02 02:05

    One gotcha with INT13 is that head and track numbers start at 0, but sector numbers for some reason start at 1. You might check that your sector-writing utility conforms to this numbering scheme.

    Questions:

    • How many dots do you see when you boot?
    • Does the floppy motor kick on?
    0 讨论(0)
  • 2021-02-02 02:06

    I am not sure what you are trying to achieve with the code, but if I understand it correctly, You want to read a few sectors from the disk into the location 0x8000 and then execute that code?

    If that is the case, then you will have to explictly make a CALL/JUMP to that particular location. The BIOS will not call that code for you. On boot, once the BIOS is initialized, it will set the Instruction Pointer IP to the address 0x7c00. The cpu will then start to execute the code sequentially, so without a JMP/CALL to 0x8000 it wont execute the code at 0x8000 until it has executed every memory address inbetween 0x7c00 to 0x8000 etc.

    So the solution would be to have a jmp or call instruction after your jc readdisk.

    If my understanding is incorrect then I apologize. Hope this helps.

    0 讨论(0)
  • 2021-02-02 02:10

    I don't know if you're using a floppy to boot your OS, but if you are using, i suggest you to declare some things after the ORG and Bits declaration, take a look(they are very important):

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

    It's a good idea to put this.

    Regards.

    0 讨论(0)
  • 2021-02-02 02:12

    I'm not sure why the code doesn't work, since I can't check the the whole environment (disk, memory dump, etc)...but what I can say is...the code is wrong. You are loading the second program, not at 0x8000 (that was the point of using 0rg 0x8000 right?), but at 0x80000.

    The reason being, you are using the segment:offset addressing in the wrong way, the address 0x8000:0x0000 is resolved to the linear address 0x80000, since the segment value is shifted left by 4 bits an then added to the offset.

    To resolve this problem, you should take a look at a memory dump and see if the program works as you expect it too....either that or you're loading the wrong sectors of the disk.

    0 讨论(0)
提交回复
热议问题