Discussion:
メモリー上の制限の有無について
(too old to reply)
unknown
2009-07-30 06:23:01 UTC
Permalink
上田です。

malloc関数でソートに使うメモリーを確保しています。
そこで前々から気になっていることがあります。
MSDOSで64Kバイトを越える大量のメモリーを運用する場合は
64Kの境界に注意することを警告されていました。
これは16ビットではアドレスがセグメントとオフセットに別れており、
オフセットが0x0000から0xffffまでとなっているためだそうです。
ソートではメモリーの交換を行ないますが、境界を含む部分を交換は
できないことになるから、必ず交換の単位は例えば8バイトのように
割り切れる数値でないと異常を来たすので要注意することと。
 それではWindowsの場合はどうなるのでしょう。確か32ビットだから
そんな事は気にしないでも大丈夫なんでしょうか。VC6ではhugeポインタの
項目が無いこと、halloc関数がなく、mallocしかないことを考えれば
そんな事(64K境界の問題)は考えなくて良いのでしょうか。
 しかし、nearとfarの記述は載っています。使えると言うことは
アドレスの考え方は同じなのでしょうか。そもそも、このアドレスの考え方は
インテルCPUだけで、AMDのCPUではセグメントとオフセットの
考え方ではなかったように記憶しているのですが。
つまり、MSDOS時代ではCPUメーカーによって対応が異なっていたと
思うのですが。
tomato
2009-07-30 20:43:39 UTC
Permalink
CPUの動作モードがDOSではリアルモード、windows95以降ではプロクテクトモードです。

プロクテクトモードにはセグメントは存在せず、CPU内のアドレス変換ユニットで、リニアアドレスを
実際のメモリのアドレスに変換して使用してます。

windowsでは、一般アプリが直接メモリを操作する事はなく、必ずwindowsが介入します。

CPUの違いよりwindowsの違いの方が問題になってきます。
Post by unknown
上田です。
malloc関数でソートに使うメモリーを確保しています。
そこで前々から気になっていることがあります。
MSDOSで64Kバイトを越える大量のメモリーを運用する場合は
64Kの境界に注意することを警告されていました。
これは16ビットではアドレスがセグメントとオフセットに別れており、
オフセットが0x0000から0xffffまでとなっているためだそうです。
ソートではメモリーの交換を行ないますが、境界を含む部分を交換は
できないことになるから、必ず交換の単位は例えば8バイトのように
割り切れる数値でないと異常を来たすので要注意することと。
 それではWindowsの場合はどうなるのでしょう。確か32ビットだから
そんな事は気にしないでも大丈夫なんでしょうか。VC6ではhugeポインタの
項目が無いこと、halloc関数がなく、mallocしかないことを考えれば
そんな事(64K境界の問題)は考えなくて良いのでしょうか。
 しかし、nearとfarの記述は載っています。使えると言うことは
アドレスの考え方は同じなのでしょうか。そもそも、このアドレスの考え方は
インテルCPUだけで、AMDのCPUではセグメントとオフセットの
考え方ではなかったように記憶しているのですが。
つまり、MSDOS時代ではCPUメーカーによって対応が異なっていたと
思うのですが。
unknown
2009-08-01 03:06:01 UTC
Permalink
上田です。
回答ありがとうございました。
今後もよろしくお願いします。

UETA, Shin-ichi
2009-07-31 06:40:50 UTC
Permalink
こんにちは、植田です。
Post by unknown
 それではWindowsの場合はどうなるのでしょう。確か32ビットだから
そんな事は気にしないでも大丈夫なんでしょうか。
Win32 API(x86)では32-bitのフラットな仮想アドレス空間(4GB)を
使います。ただし、実際に使えるのは2GBまでで(一部のサーバー
用Windowsは3GBまで可)、残りはシステムで予約されています。
セグメントの概念そのものは現在でもありますが、かつての64KB
境界の制限はなくなりました。

# ただし、Win9x系の場合、16-bitのコードが残っているため、最大
# 値が64KBで制限されているAPIが多くあります。
# しかしそれはアプリケーションのアドレス空間とは関係のない話で、
# Windowsの内部情報の管理方法に原因があります。
# 詳しいことはこちら↓を参考にしてください。
# 特集:Windows 9x or Windows 2000 ? - @IT
# http://www.atmarkit.co.jp/fwin2k/special/win9xorwin2k/

最近では64-bit版も無視できなくなりつつあるので、ポインタが32-bit
であることを前提としたコーディング(たとえばポインタとlongの交換)
を避けるように勧められており、ポインタと整数を排他的に取る引数
のために新たな型が定義されていたりします。
Post by unknown
 しかし、nearとfarの記述は載っています。使えると言うことは
アドレスの考え方は同じなのでしょうか。
後方互換(Win16資産の継承)を意図したもので、Win32 API では
意味のない属性です。

# マクロの定義をご覧になってみては? windef.h にあります。

APIで定義されている型や引数の名前に、たとえば、LPSTR 、
lpCmdLine など、farポインタを意味するプレフィックス(LP、lp) が
ついていたりしますが、実際にはnearポインタとfarポインタの区別
はありません。

# 強いて言えばポインタはすべてhugeポインタ。
Post by unknown
そもそも、このアドレスの考え方は
インテルCPUだけで、AMDのCPUではセグメントとオフセットの
考え方ではなかったように記憶しているのですが。
# 「AMDのCPU」といっても、MIPSはともかく、x86アーキテクチャの
# CPUの方が有名かと。

もちろんCPUのアーキテクチャによってポインタの形式は違います。
いわゆるセグメント方式のメモリ管理はx86アーキテクチャの特徴
ですが、80386でセグメントが拡張されてからはアプリケーションが
それを意識しなくても済むようになりました。

ちなみに、Windowsはx86をプロテクトモードで動かしますが、リアル
モード(8086と同等)や仮想86モードと異なり、セグメントレジスタは
セグメントアドレスを保持しているわけではありません。
また、セグメントを切り替える必要性がなくなったので、0を基点とした
4GBのセグメントを1つだけ使い(フラットメモリモデル)、ページ単位
(4KB単位)でメモリを保護しています。
Post by unknown
つまり、MSDOS時代ではCPUメーカーによって対応が異なっていたと
思うのですが。
CPUメーカーというより、たとえば、PC-9800用とか、PC/AT互換機用
とか、PCの機種ごとにMS-DOSやMS-Cがリリースされていただけでは?
MS-DOSはx86を搭載したPCを対象としているので、それ以外のCPU
を採用した機種では他のOSが使われていたのではないかと...。

# PC本体を指して「CPU」と呼ぶ場合もありますけど(苦笑)

現在ではPCのアーキテクチャが事実上PC/AT互換機(死語?)で統一
されており、ハードウェアの細かい違いはWindowsとデバイスドライバ
によって吸収されているので、アプリケーションがx86用にビルドされて
いるかぎり、CPUがIntel製であろうとAMD製であろうと問題なく動きます。
--
植田システム設計事務所
Ueta System Design Studio
http://www.usdesign.jp/
植田真一
mailto:***@usdesign.jp
unknown
2009-08-01 03:04:01 UTC
Permalink
上田です。
丁寧な説明ありがとうございます。
安心しました。
Continue reading on narkive:
Loading...