【问题标题】:Generating address of a instruction using Code Segment and Instruction Pointer使用代码段和指令指针生成指令的地址
【发布时间】:2020-04-29 20:50:05
【问题描述】:

假设代码段地址为 FE00,指令指针为 ABBE。将代码段移动 4 位并添加指令指针会导致额外的进位。我们如何表示生成的地址?

【问题讨论】:

  • 8086 线性地址为 20 位宽;您需要 2 个寄存器和 adc 从低 16 位到高 4 位的进位。
  • @Peter Cordes:实际上,由于(Real/Virtual)86 模式中的 286 个线性地址是 21 位宽,因为高位可以执行低 20 位。因此 A20(第 21 个地址线)。

标签: x86-16 microprocessors real-mode memory-segmentation


【解决方案1】:

假设代码段地址为 FE00,指令指针为 ABBE。我们如何表示生成的地址?

要么你将地址表示为

  • 0FE00h:0ABBEh,它的分段形式使用两个由冒号分隔的 16 位数字,并且总是(段 - 冒号 - 偏移)
  • 00108BBEh,使用一个 32 位数字的线性形式

无论您选择什么,在 8086 上总是需要 2 个字大小的寄存器。

指令指针是64KB内存段中的一个偏移量,从CS代码段寄存器中的值乘以16得到的线性地址开始(与左移 4 次相同)。”

计算线性地址可能效率低(但容易理解),如下所示:

mov     ax, 0FE00h  ; The code segment
mov     dx, 16
mul     dx          ; "shifting the code segment by 4 bits"
add     ax, 0ABBEh  ; "adding the instruction pointer"
adc     dx, 0       ; Taking care of the additional carry

这个线性地址 00108BBEh 使用 2 个寄存器 AXDXAX 寄存器将保存最低有效部分 8BBEh,DX 寄存器将保存最高有效部分 0010h。如果你需要引用整对寄存器,你可以像DX:AX 那样做。所以 highWord - 冒号 - lowWord。

与 seg:off 表示法不同,这只是一个 32 位数字,分为 2 个寄存器,没有重叠的位值。当我们谈论一个扁平的 32 位(或 20 位)数字时,高半部分的低位具有 2^16 位值,而不是 seg:off 地址。

【讨论】:

  • 通常从最高有效寄存器到最低有效寄存器描述形成单个更宽值的寄存器组。所以你通常会看到 DX:AX(高字:低字)。英特尔文档也几乎采用了该约定。
  • @MichaelPetch 你是对的。我的脑子里一定已经开始思考这个值是如何存储在内存中的......
  • 如果你真的要运行它(特别是在 8086 上),你会避免 mul 并手动执行扩展精度左移。例如,使用shl / adc dx,dxmov dl, ah 在循环中一次将高4 位提取到另一个寄存器的底部; shr dl, 4 (186) ; mov dh, 0。或者,如果您有高效的班次(不是每个时钟 1 个计数)mov dx, axshr dx, 12
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2020-12-30
相关资源
最近更新 更多