什么是段以及如何在 8086 模式下对其进行寻址? [英] What are Segments and how can they be addressed in 8086 mode?

查看:12
本文介绍了什么是段以及如何在 8086 模式下对其进行寻址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从我开始使用 8086 汇编语言编程以来,我一直在思考这些段和段寄存器.我面临的问题是我无法直观地了解脑海中的片段,因此我不清楚这些概念.

<小时>
  • 谁能帮我理解将其与现实世界场景联系起来的概念?我还有以下问题:

问题 1:

据我了解,在启用 20 条地址线的 16 位实模式下,我们可以将物理内存分成 16 段,每段 64KiB.第一段从 0x00000 开始.下一段的起始地址是什么.会是通过添加 0x10000 (65536 = 64KiB) 吗?

问题 2:

在这里问这个问题有点奇怪,但仍然是我唯一的选择.假设如果给我一个偏移地址0x6000,我怎样才能找到它所属的段以便解决它.

谢谢

解决方案

...我们可以将物理内存分成 16 段,每段 64KiB.

没错,但更准确的说法是将其表述为16 个不重叠段",因为也有可能将内存划分为 65536 个重叠段.

启用 A20 线后,我们可以使用超过 1MB 的空间.(1048576+65536-16) 将相关段寄存器设置为 0xFFFF 时,我们可以访问 0x0FFFF0 和 0x10FFEF 之间的内存.

这两种细分的主要特点是:

  1. 不重叠的片段
    • 包含 65536 个字节.
    • 在内存中相隔 65536 个字节.
    • 这是我们人经常方便地查看记忆的方式.它使我们能够说我们已经把
      • A 段 (0xA0000-0xAFFFF) 中的图形窗口
      • B 段 (0xB0000-0xBFFFF) 中的文本视频窗口
      • F 段中的 BIOS (0xF0000-0xFFFFF)
  2. 重叠片段

    • 包含 65536 个字节.
    • 在内存中相隔 16 个字节.

      有时您会看到人们将 16 字节的内存块称为段,但显然这是错误的.然而,这样的内存量有一个广泛使用的名称:paragraph".

    • 这是CPU(在实地址模式下)查看内存的方式.
      处理器使用以下步骤计算线性地址:
      • 首先计算指令操作数的偏移地址.结果被截断以适应 16 位(64KB 环绕).
      • 接下来添加SegmentRegister * 16的乘积
        如果 A20 行处于非活动状态,则结果将被截断以适应 20 位(1MB 环绕).
        如果 A20 线处于活动状态,则按原样使用结果,因此不会发生 1MB 回绕.

<块引用>

假设如果给定的偏移地址为 0x6000,我怎样才能找到它所属的段以便对其进行寻址.

这里的问题又出在措辞上!

如果0x6000 的偏移地址"是指我们通常在实地址模式编程中使用的偏移量,那么问题无法回答,因为存在的每个段中都有这样的偏移量 0x6000

另一方面,如果0x6000的偏移地址"实际上是指线性地址 0x6000,那么对于段寄存器有很多解决方案:

segment:offset--------------0000:60000001:5FF00002:5FE00003:5FD0...05FD:003005FE:002005FF:00100600:0000

如您所见,有 0x0601 个可能的段寄存器设置可以到达线性地址 0x6000.
以上适用于A20线确实启用的情况.如果 A20 处于非活动状态,那么线性地址 0x6000(就像从 0 到 1MB-1 的任何其他线性地址一样)可以精确地以 0x1000 (4096) 方式到达:

segment:offset--------------F601:FFF0F602:FFE0F603:FFD0...FFFD:6030FFFE:6020FFFF:60100000:60000001:5FF00002:5FE00003:5FD0...05FD:003005FE:002005FF:00100600:0000

Ever since I started with 8086 Assembly Language programming, I have been hammering my mind about these Segments and Segment registers. The problem I am facing is that I can't have a visual image of what segments are in my mind and therefore the concepts are not clear to me.


  • Can anyone help me understand the concept relating it to a real world scenario? Also I have the following questions:

Question 1:

As far as I have understood, In 16-bit real mode with 20 address line enabled, we could divide the physical memory into 16 segments with 64KiB each. The first segment starts at 0x00000. What will be the starting address of next segment. Will it be by adding 0x10000 (65536 = 64KiB)?

Question 2:

This question is a bit odd to ask here but still SO is my only option. Suppose if I am given with an Offset address of 0x6000, How can I find the segment to which it belongs in order to address it.

Thanks

解决方案

...we could divide the physical memory into 16 segments with 64KiB each.

True, but more exact would be to phrase this as "16 non-overlapping segments" since there's also the possibility to divide the memory into 65536 overlapping segments.

When the A20 line is enabled, we have more than 1MB to play with. (1048576+65536-16) When setting the relevant segment register to 0xFFFF, we can gain access to the memory between 0x0FFFF0 and 0x10FFEF.

The main features of both kinds of segments are:

  1. Non-overlapping segments
    • Contain 65536 bytes.
    • Are 65536 bytes apart in memory.
    • This is the way us people often conveniently view memory. It enables us to say that we've put
      • the graphics window in the A-segment (0xA0000-0xAFFFF)
      • the text video window in the B-segment (0xB0000-0xBFFFF)
      • the BIOS in the F-segment (0xF0000-0xFFFFF)
  2. Overlapping segments

    • Contain 65536 bytes.
    • Are 16 bytes apart in memory.

      Sometimes you'll see people refer to a 16-byte chunk of memory as a segment but obviously this is wrong. There is however a widely used name for such an amount of memory : "paragraph".

    • This is the way the CPU (in the real address mode) sees memory.
      The processor calculates the linear address using next steps:
      • First is calculated the offset address from the operands of the instruction. The result is truncated to fit in 16 bits (64KB wraparound).
      • Next is added the product of SegmentRegister * 16
        If the A20 line is inactive the result is truncated to fit in 20 bits (1MB wraparound).
        If the A20 line is active the result is used as is and thus no 1MB wraparound occurs.

Suppose if I am given with an Offset address of 0x6000, How can I find the segment to which it belongs in order to address it.

Here again the problem lies in the phrasing!

If by "an Offset address of 0x6000" you mean an offset like the one we normally use in the real address mode programming then the question cannot be answered since there is such an offset 0x6000 in every segment that exists!

If on the other hand the wording "an Offset address of 0x6000" actually refers to the linear address 0x6000 then there are a lot of solutions for the segment register:

segment:offset
--------------
   0000:6000
   0001:5FF0
   0002:5FE0
   0003:5FD0
   ...
   05FD:0030
   05FE:0020
   05FF:0010
   0600:0000

As you can see there are 0x0601 possible segment register settings to get to linear address 0x6000.
The above applies to when the A20 line is indeed enabled. If A20 was inactive then the linear address 0x6000 (just like any other linear address from 0 to 1MB-1) can be reached in precisely 0x1000 (4096) ways:

segment:offset
--------------
   F601:FFF0
   F602:FFE0
   F603:FFD0
   ...
   FFFD:6030
   FFFE:6020
   FFFF:6010
   0000:6000
   0001:5FF0
   0002:5FE0
   0003:5FD0
   ...
   05FD:0030
   05FE:0020
   05FF:0010
   0600:0000

这篇关于什么是段以及如何在 8086 模式下对其进行寻址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆