将磁盘扇区加载到内存中(AT&T)

问题描述 投票:0回答:1

我想将一个扇区加载到从(0xD000)开始的内存地址中。我使用索引寻址通过 0x13 BIOS 中断来完成磁盘加载。使用16位模式、BIOS、AT&语法汇编。

我很难想象如何使用这些函数迭代多个字节以连续打印出十六进制数字,以查看磁盘扇区中存储的内容。我知道我会使用“cx”等寄存器来创建计数器和循环函数。我应该使用“jmp”或“loop”调用吗?

read_sector:  
    movw    $disk_address_packet, %si
    movw    $1, 2(%si)
    movw    $0xD000, 4(%si)
    movw    $1, 8(%si)
    movb    $0x42, %ah
    movb    (boot_device), %dl
    int     $0x13
    jc      read_failed
    
    movb    (0xD000), %al             # Check for non-empty bytes
    cmpb    $0, %al
    je      read_failed

我发现这个函数可以读取字节并输出为十六进制

cons_write_hex:
    movw    $4, %cx
    movb    $0x0E, %ah
    
hexloop:
    rol     $4, %bx             # rotate left 4 bits
    movw    %bx, %si
    and     $0x000F, %si
    movb    HexChars(%si), %al
    int     $0x10
    loop    hexloop
    ret
loops assembly x86-16 att bios
1个回答
0
投票
movw    $0xD000, 4(%si)
movw    $1, 8(%si)

在 disk_address_packet 中,如果还不是这种情况,请确保

4(%si)
处的远指针有效。可能您可能仍然需要插入段值:

movw    $0xD000, 4(%si)
movw    %ds, 6(%si)       # far pointer is %ds:0xD000
movw    $1, 8(%si)

我发现这个函数可以读取字节并输出为十六进制

该特定代码输出十六进制单词,因此 2 个字节在一起!
对于仅字节,它看起来像这样:

; IN (%bl)
cons_write_hex:
    movw    $2, %cx
    movb    $0x0E, %ah
hexloop:
    rol     $4, %bl             # rotate left 4 bits
    movw    %bx, %si
    and     $0x000F, %si
    movb    HexChars(%si), %al
    int     $0x10
    loop    hexloop
    ret

...我将如何使用这些函数迭代多个字节以连续打印出十六进制数字,以查看磁盘扇区中存储的内容。

此任务有不止一种解决方案,但可以十六进制转储整个 512 字节扇区的循环可以这样编写:

  movb    $0x0E, %ah          # BIOS.Teletype
  xorw    %bx, %bx            # have %bh permanently zero
  movw    $0xD000, %si        # where the 512 bytes are in memory
hexloop:
  movb    (%si), %bl          # load current byte
  shr     $4, %bl             # get high nibble into the low 4 bits
  movb    HexChars(%bx), %al  # fetch hexadecimal digit (char)
  int     $0x10
  movb    (%si), %bl          # load current byte again
  and     $15, %bl            # keep only low nibble
  movb    HexChars(%bx), %al  # fetch hexadecimal digit (char)
  int     $0x10
  movb    $' ', %al           # interject a space char for readability
  int     $0x10
  incw    %si                 # point at next byte
  cmpw    $0xD200, %si
  jb      hexloop             # addresses that are below 0xD200
                              # fall inside the sector, so go repeat

我知道我会使用“cx”等寄存器来创建计数器和循环函数。我应该为此使用“jmp”还是“loop”calls

如你所见,我在上面的循环中既没有使用

%cx
寄存器,也没有使用
loop
指令1。一般来说,最好不要使用
loop
指令,而是依赖条件跳转,就像我展示的那样。

1 术语:它不是函数,也不是调用

jmp
loop
说明

© www.soinside.com 2019 - 2024. All rights reserved.