我想将一个扇区加载到从(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
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
是 说明。