12 Extended Memory Access Using Segments

當 CPU 執行在 16-bit mode 時,表示 register 的最大 size 為 16 bit。這表示最大的 address 是 0xffff,也就是 memory 最大只能到 64KB。

那如果 memory 的 size 超過 64KB 該怎麼辦呢?

在 16-bit 下,我們可以用 special register csdsss 以及 es――稱為 segment register――來超過 64KB 的 memory size 限制。

我們將 memory 想像成被切成好幾塊 segment,這些 segment 以 segment register 為 index。當我們指定某個 16-bit address 時,CPU 會自動以某個 segment register 及我們指定的 address 計算出真正的 memory address。

其中這「某個」segment register 如何決定的?除非特別指定,否則 CPU 會以 instruction 的 context 來決定要用哪個 segment register。例如 mov ax, [0x34ef] 的 instruction 就會預設使用 data segment ds

那麼 CPU 是怎麼計算實際 address 的呢?

CPU 會將 segment register 的值乘 16,再加上我們指定的 address(也就是 offset)得到實際 address。因為我們通常用 16 進位表示 register 的值,例如 0x32,乘 16 就是將 16 進位的數字左移一格,變成 0x320。如果我們設定 ds0x32,則 mov ax, [0x20][0x20] 實際 address 是 0x320 + 0x20 = 0x340

另外,segment register 無法直接用 mov 來 assign 值,需要先將值放到 general register,再 mov 到 segment register 裡,如下:

1
2
mov ax, 0x123
mov ds ds, ax

segment-based 的 address 方式讓我們可以使用更多 memory,因為總共的 address 可以有 0xffff * 16 + 0xffff 個,也就是 1MB 多一點。