-

「LIBRARIES PUBLIC DOCUMENT MEMUTIL」の版間の差分

提供: HI-TECH C for CP/M Fan WIKI(JP)
移動先: 案内検索
(HI-TECH Cのメモリアドレス管理)
(HI-TECH Cのメモリアドレス管理)
27行目: 27行目:
 
これを図式したものが次の図です。
 
これを図式したものが次の図です。
  
{|class="wikitable"
+
{|
 
|-
 
|-
 
|scope="row" colspan="2"| low
 
|scope="row" colspan="2"| low
 
|-
 
|-
|<nowiki>-Pdata=xxxx -></nowiki>||data psec
+
|<nowiki>-Pdata=xxxx -></nowiki>||------------
 
|-
 
|-
|<nowiki>-Pbss=xxxx -></nowiki>||bss psect
+
| ||<nowiki>|data psect|</nowiki>
 
|-
 
|-
|<nowiki>__Hbss </nowiki>||ヒープ
+
|<nowiki>-Pbss=xxxx -></nowiki>||------------
 
|-
 
|-
|<nowiki>-Pbss=xxxx -> </nowiki>||スタック(auto変数)
+
| ||<nowiki>|bss psect |</nowiki>
 
|-
 
|-
|<nowiki>-Pbss=xxxx -> </nowiki>||システム・ワークなど
+
|<nowiki>__Hbss </nowiki>||------------
 +
|-
 +
| ||<nowiki>|ヒープ    |</nowiki>
 +
|-
 +
|<nowiki>-Pbss=xxxx -> </nowiki>||------------
 +
|-
 +
| ||<nowiki>|スタック  |</nowiki>
 +
<nowiki>|(auto変数)|</nowiki>
 +
|-
 +
|<nowiki>-Pbss=xxxx -> </nowiki>||------------
 +
|-
 +
| ||<nowiki>|システム  |</nowiki>
 +
<nowiki>|ワークなど|</nowiki>
 +
|-
 +
| ||------------
 
|-
 
|-
 
|scope="row" colspan="2"| high
 
|scope="row" colspan="2"| high

2017年8月13日 (日) 11:15時点における版

HI-TECH C用メモリ管理ユーティリティー関数について By Tatsuhiko Syoji

関係ファイル一覧

SBRK .AS 
改良を加えたsbrk関数及び、setheaptop,getheaptop関数のソースです。
SBRK .AS 
改良を加えたsbrk関数及び、setheaptop,getheaptop関数のオブジェクトです。
MEMUTIL .H 
setheaptop,getheaptop関数のヘッダーファイルです。
MEMUTIL .H 
setheaptop,getheaptop関数のマニュアルとメモリ管理に関する解説です。

これは何か?

HI-TECH C標準のメモリ管理関数であるsbrk関数に手を加えて、任意のアドレスのメモリブロックを取得できるようにしました。 この関数は、HI-TECH Cのメモリアドレス管理について理解していないと暴走の原因を生むので、HI-TECH Cのメモリ管理について理解した上で、利用者の責任で利用してください。

HI-TECH Cのメモリアドレス管理

HI-TECH Cでは、大きく分けて、5つの方法でメモリを管理しています。

1つめは、data psectによるもので、初期値のあるグローバル変数や、初期値のある関数内のstatic指定された変数がこのグループに属し、ブロック化されます。このグループの変数のメモリアドレスは、リンカの-Pオプションがある場合は、(-Pdata=1000H)-Pオプションで指定したブロックの先頭アドレスに、アドレス指定が無い場合、text psectの直後のアドレスに配置されます。

2つめは、bss psectによるもので、初期値の無いグローバル変数や、初期値の無い関数内のstatic指定された変数がこのグループに属し、ブロック化されます。このグループの変数のメモリアドレスは、リンカの-Pオプションがある場合は、(-Pbss=1000H)-Pオプションで指定したブロックの先頭アドレスに、アドレス指定が無い場合、data psectの直後のアドレスに配置されます。

3つめはスタックを利用したもので、auto変数がこのグループに属します。関数が呼ばれた際に、内部関数ncsv関数によって、スタックから変数のための領域が確保され、内部関数cret関数によって開放されます。

4つめは、アセンブラのorg命令でアドレス指定したメモリ領域です。メモリアドレスは、org命令の指定と、以降のプログラムコードの命令長、データ長で決定します。

最後になるのが、ヒープから取得されるメモリで、sbrk,malloc,calloc関数によって取得されるメモリブロックがこの方法によって管理されます。malloc,calloc関数を実行すると、ヒープの先頭からスタックに向かって、より高位アドレスのメモリを取得するようになります。ヒープの先頭は、システム定義シンボル__Hbssで示されるbss psectの終わり以降になります。 これを図式したものが次の図です。

low
-Pdata=xxxx -> ------------
|data psect|
-Pbss=xxxx -> ------------
|bss psect |
__Hbss ------------
|ヒープ |
-Pbss=xxxx -> ------------
|スタック |

|(auto変数)|

-Pbss=xxxx -> ------------
|システム |

|ワークなど|

------------
high

setheaptop関数の働き

setheaptop関数は、ヒープの先頭アドレスを変更し、任意のアドレスからメモリを取得するように働きかける働きを持っています。(malloc,calloc関数の管理領域があるので、厳密にアドレスを指定できる訳ではありませんが。) 下の図で例を示します。 low -Pdata=xxxx -> ------------ |data psect| | | -Pbss=xxxx -> ------------ |bss psect | | | __Hbss -> ------------ | | | | setheaptopで ------------ 指定したアドレス| | |ヒープ | | | | | |/ | | | | | | /| | | | | -Pbss=xxxx -> ------------ |スタック | |(auto変数)| -Pbss=xxxx -> ------------ |システム | |ワークなど|


high

これにより、任意のアドレスの任意の大きさのメモリブロックを取得して、利用することができるようになります。 この関数が必要な訳として、MSXでのプログラミングにおいて、特定のアドレスにデータを置く必要がある場合があります。たとえば、割り込みから参照されるデータは、ページ1(4000H)以降に存在する必要があります。data psectやbss psectを使えば、特定のアドレスへのデータは位置ができますが、実行ファイルにもその分の領域が含まれるので、ファイルサイズの無駄が大きくなります。auto変数を使うと、スタックを消費するので、スタックがページ3にある必要がある場合などに不都合が生じます。 そこで、この関数を使って、任意の位置のメモリブロックを取得するようにすることで、これらの不都合を回避することができるという訳です。

それなら、こんな関数を通さないで、メモリが空いていると仮定して、直接アドレスを指定すれば良いのでは?と思われるかもしれません。ただその場合、複数のメモリブロックを扱う場合、ユーザーがアドレスが重複しないように計算して、メモリを割り付けていく必要があったり、スタックと領域が重なる恐れがあったりと面倒で、リスクも伴います。この関数を使うことで、スタックとのメモリ領域の重複チェックや、次に割り付けるメモリブロックの先頭アドレスの計算が自動的に行われるので、ユーザーは、苦労なくヒープ内のメモリブロックを扱えると共に、アドレス指定の自由度も向上するというのが、本パッケージの売りです。

使い方

HI-TECH Cをインストールした後、ヘッダファイルのある場所にMEMUTIL.Hをコピーします。 次に、libr.com(HI-TECH C付属),libc.lib(HI-TECH C付属のものもしくは相当するファイル),sbrk.obj(本パッケージのもの)を用意して、 libr r libc.lib sbrk.obj を実行することで、本パッケージのインストールが終了します。 これで、memutil.hをインクルードし、インストール終了後のlibc.libをリンクすることにより、本パッケージの関数を利用する事ができます。

関数の使い方

void setheaptop(unsigned int addr) ヒープの先頭アドレスをaddrで指定したアドレスに移動します。malloc,calloc関数利用前の利用が効果的です。 unaigned int getheaptop(void) 現在未使用のヒープの先頭アドレスを獲得します。malloc,calloc,setheaptop関数を一度も使わない状態でこの関数を呼び出すと0を返します。

著作権他

 本ライブラリのライセンスはHI-TECH C for CP/M Version 3.09のソースファイルを改変しているためHI-TECH C for CP/M Version 3.09のライセンスに従います。

オリジナルのZ80READ.MEより引用

The HI-TECH Z80 CP/M C compiler V3.09 is provided free of charge for any
use, private or commercial, strictly as-is. No warranty or product
support is offered or implied.
You may use this software for whatever you like, providing you acknowledge
that the copyright to this software remains with HI-TECH Software.

追加した関数については作者であるTatsuが著作権を所有しています。