【问题标题】:How to increment 64-bit memory effective address in Real Mode如何在实模式下增加 64 位内存有效地址
【发布时间】:2017-05-07 14:07:17
【问题描述】:

我正在使用带有扩展驱动器功能0x42 的中断0x13 在实模式下从扩展驱动器读取扇区。

我在以下结构中将 DAP 定义为 16 个字节:

DAP:
    db  0x10        ; size of DAP
    db  0           ; Reserved zero
    dw  0x0001      ; Number of sectors to read
    dd  0x00000200  ; Memory Location to load the sector (s)
    dq  0           ; Start of the sectors to be read

如您所见,DAP 段的长度为 8 字节。在寻找我的扇区(循环扇区)期间,我增加了该段并将其与我的驱动器的实际大小进行比较。我用来递增的错误代码仅限于 16 位模式:

mov     ax, [DAP+0x08]
inc     ax
mov     [DAP+0x08], ax

我不想在复杂的寻址模式下使用几个通用寄存器来达到我的目的,我想你有一些简单有效的方法。

【问题讨论】:

  • 段不是 8 字节(64 位值)。您列出的 8 字节值是 LBA(逻辑块地址)。段。实际上是您列为offset 的内容的第二个2 个字节。您列为offset 的四个字节值实际上是实模式段:偏移量对。
  • @MichaelPetch,您对我的代码 cmets 是正确的。这是由于从某个地方复制部分代码的错误。反正我修改了代码cmets。
  • 4 字节值 0x200 实际上与 0x00000200 相同,转换为 0x0000:0x0200 的段偏移对。我希望这不是您开始读取扇区的内存位置,因为它恰好位于从 0x0000 到 0x3fff 的较低内存中的中断向量表的顶部。之后是从 0x400 到 0x4ff 的 BIOS 数据区。在古老的硬件上,有从 0x500 开始的保留字节。我建议开始阅读 0x0000:0x0600
  • 为了便于阅读,我会将dd 0x00000200 拆分为两个单独的 16 位字。并将其设置为 dw 0x0000 ; offset 后跟 dw 0x07e0 ; segment 表示 0x07e0:0x0000 是物理地址 (0x07e0
  • 读错内存地址可不是小问题。这是一个错误。

标签: assembly x86 nasm real-mode fat16


【解决方案1】:

要增加 64 位 QWORD,您可以使用 addadc 指令:

ADD WORD [DAP+ 8], 1
ADC WORD [DAP+10], 0
ADC WORD [DAP+12], 0
ADC WORD [DAP+14], 0

或者,如果您的目标不是 8088、8086 或 80286,您也可以使用 32 位 add/adc:

ADD DWORD [DAP+ 8], 1
ADC DWORD [DAP+12], 0

请注意,您不能使用INC WORD [DAP+ 8] 代替ADD WORD [DAP+ 8], 1,因为前者不会设置进位标志。

【讨论】:

  • 谢谢@FUZ。我正在使用 NASM,他们现在不适合我,我会回来的。
  • @fuz:如果你有 FPU (FILD qword [DAP+8] / FLD1 / FADDP / FISTP qword [DAP+8]),你也可以直接使用 FPU。诚然很糟糕,但 x87 具有足够的精度和正确的溢出语义来做正确的事情。
  • @doynax 确实可行,但效果可能会更差。
  • 如果您使用 x87 FPU 执行此操作,性能会很多变差。精度在这里并不重要,这些是整数。它还会降低代码的可读性。使用大整数算术的标准习语:带进位加法。
  • 我认为他所说的精度是使用浮点数可以精确地表示 0 到 (2^64)-1 之间的所有值,因为 FPU 内部使用的是 80 位浮点数表示其中 64 位用于有效位
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2012-08-13
  • 1970-01-01
  • 2017-03-20
相关资源
最近更新 更多