Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly—读取虚拟磁盘的下一个扇区_Assembly_X86 16_Hard Drive_Osdev_Sector - Fatal编程技术网

Assembly—读取虚拟磁盘的下一个扇区

Assembly—读取虚拟磁盘的下一个扇区,assembly,x86-16,hard-drive,osdev,sector,Assembly,X86 16,Hard Drive,Osdev,Sector,作为世界上任何一个程序员,在他/她的一生中至少有一次,我正在努力创造我的“革命性”操作系统,这是一种全新的、唯一的操作系统D 我使用的是一个虚拟仿真器(Oracle VM virtual Box),我为它创建了一个新的未知操作系统,带有一个vmdk磁盘。我喜欢vmdk,因为它们只是普通文件,所以我可以将引导加载程序粘贴到虚拟硬盘的前512字节上 现在,我正在尝试读取这个虚拟磁盘的下一个扇区,我将在该扇区上粘贴一个简单的内核,该内核将显示一条消息 我有两个问题: 我是否正确读取了第二段(第一段5

作为世界上任何一个程序员,在他/她的一生中至少有一次,我正在努力创造我的“革命性”操作系统,这是一种全新的、唯一的操作系统D

我使用的是一个虚拟仿真器(Oracle VM virtual Box),我为它创建了一个新的未知操作系统,带有一个vmdk磁盘。我喜欢vmdk,因为它们只是普通文件,所以我可以将引导加载程序粘贴到虚拟硬盘的前512字节上

现在,我正在尝试读取这个虚拟磁盘的下一个扇区,我将在该扇区上粘贴一个简单的内核,该内核将显示一条消息

我有两个问题:

  • 我是否正确读取了第二段(第一段512字节,被引导加载程序占用)? 代码:


    在这里,我在检查CF之后得到错误消息。但是,如果我使用INT 13,1得到最后一个 状态消息,AL为0-因此不保存任何错误

  • 我是否将简单内核粘贴到vmdk中的正确位置?我所做的是将其粘贴在文件的512字节之后,如我所说,前512字节是引导加载程序。 该文件如下所示:

    BE 45 7C E8 16 00 EB FE B4 0E B7 00 B3 07 CD 10 <- First sector
    C3 AC 08 C0 74 05 E8 EF FF EB F6 C3 B4 00 B2 80
    CD 13 BE 5D 7C 72 F5 BB 00 80 8E C3 BB 00 00 B4 
    02 B0 06 B5 00 B1 01 B6 00 B2 07 CD 13 BE 4E 7C 
    72 CF 26 FF 27 57 65 6C 63 6F 6D 65 21 00 52 65 
    61 64 69 6E 67 20 65 72 72 6F 72 21 00 52 65 73 
    65 74 74 69 6E 67 20 65 72 72 6F 72 21 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA <- Boot-loader signature
    B4 0E B0 2E CD 10 EB FE 00 00 00 00 00 00 00 00 <- Start of the second sector
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    

    失败后再试一次。我认为当磁盘旋转时,您将收到一个没有消息的错误指示,因此模拟器可能会在第一次故意失败。四次尝试对我在博克斯和qemu都很有效,但我没有在其他任何地方尝试过。您可能还需要在读取之前重置驱动器控制器,以清除以前的任何错误。使用中断0x13清除
    al
    dl
    中的驱动器号


    注意:硬编码驱动器号目前可能有效,但不支持从其他驱动器引导。启动引导加载程序时,BIOS应将驱动器号保留在
    dl
    中,这样您就可以保存驱动器号了。

    这里有一个问题:

    jmp [es:bx]
    
    [org 0x8000]
    
    这将从寄存器
    es
    (段部分)和
    bx
    (偏移部分)中包含的地址处的内存位置读取一个地址,实际上是一个16位偏移量,然后将
    ip
    设置为该16位偏移量

    您可能希望使用的替代方法是:

    jmp some_constant1:some_constant2
    
    这将把
    cs
    设置为
    some\u constant1
    ip
    设置为
    some\u constant2
    。毫不奇怪,这两个常量的最佳候选值分别为0x8000和0,因为这是加载代码的位置

    现在,第二个问题是:

    jmp [es:bx]
    
    [org 0x8000]
    
    这个
    org
    告诉NASM生成代码的方式,如果在偏移量0x8000处加载,它将工作。现在,偏移量0x8000与段0x8000不同。如果使用
    jmp 0x8000:0
    ,则还应使用:

    [org 0]
    

    我还是得不到我想要的。未显示任何错误,但未执行加载到内存中的代码。查看更新
    bh
    bl
    也会影响打印功能的结果。我个人会使用中断0x10函数0设置视频模式,并直接写入视频内存。此外,如果使用0x8000作为段,则线性地址为0x80000,因此
    org
    指令是错误的。对于该程序,只有当该位置的ram不存在时,才会出现问题。如果可以的话,你应该连接一个调试器并确保处理器跳转到正确的位置。你真的应该去那里询问它。并阅读其wiki上的一些文章。“但是,如果我使用INT 13,1获取最后一条状态消息,AL为0-因此不会保存任何错误。”状态实际上是在
    ah
    中返回的,而不是
    AL
    。请参阅--此外,当所有操作以
    CY
    (进位标志设置)返回时,都会返回
    ah
    中的状态,您不需要显式调用函数01h。