gg02_0006
の編集
https://k.osask.jp/klog/?gg02_0006
[
トップ
] [
編集
|
差分
|
バックアップ
|
添付
|
リロード
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
2012_0001
2013_0001
2013_0002
2013_0003
2014_0001
2015_0001
2016_07
2016_08
2016_09
2016_10
2016_11
2017_01
2017_02
2017_03
2017_04
2017_05
2018_01
2019_01
BracketName
FormattingRules
FrontPage
Help
InterWiki
InterWikiName
InterWikiSandBox
K
KH_SARC_00
KH_dha8
MenuBar
PHP
PukiWiki
PukiWiki/1.4
PukiWiki/1.4/Manual
PukiWiki/1.4/Manual/Plugin
PukiWiki/1.4/Manual/Plugin/A-D
PukiWiki/1.4/Manual/Plugin/E-G
PukiWiki/1.4/Manual/Plugin/H-K
PukiWiki/1.4/Manual/Plugin/L-N
PukiWiki/1.4/Manual/Plugin/O-R
PukiWiki/1.4/Manual/Plugin/S-U
PukiWiki/1.4/Manual/Plugin/V-Z
RecentDeleted
SandBox
VC_install
WikiEngines
WikiName
WikiWikiWeb
YukiWiki
fdpl_memo0001
fdpl_memo0002
fdpl_memo0003
fdpl_memo0004
fdpl_memo0005
fdpl_memo0006
fdpl_memo0007
fdpl_memo0008
fdpl_memo0009
fdpl_memo0010
gg02_0004
gg02_0005
gg02_0006
gg02_0007
gg02_0008
gg02_0009
https
impressions
memo0001
memo0002
oisix01
osaskology
osaskology0
osecpu_0001
osecpu_0002
p20200229a
p20200303a
p20200310a
p20200321a
p20200401a
p20200730a
p20201230a
p20220628a
p20220701a
populars
prog_0001
prog_0002
prog_0003
prog_0004
prog_0005
* 第三世代OSASKの仮想CPUの仕様(2) -(by K, 2013.03.09) --(osask.netに書こうと思ったんだけどパスワードを忘れて新規ページが作れない。メモを見つけるまでこっちに書いておく) -今回はメモリアクセスに関する話に限定 --これは結構重要なので、たくさん書くことがある。 --普通のCPUとはかなり異なる。 --そしてCLEとの違いが大きいのもここかもしれない。 ** 基本的な仕組み -アドレスレジスタは、必ずなんらかの構造体のポインタが入る(もしくはNULL)。プログラム上ではそれは一時的に void * でキャストされてそのように扱われるかもしれないけど、それとは無関係にアドレスレジスタのさす先は、何らかの構造体がなければいけない。 -ポインタのキャストは認めるが、メモリ上に展開されている構造体とマッチしないようなキャストは許さない。 -これらを言語レベルではなく、仮想機械語レベルで保証する。 -mallocの際には構造体を指定しなければならず、メモリ確保成功の場合、それはOS側にも登録される。つまりmallocは領域のサイズだけではなく、領域の構造体情報も含めて記録している。 --この構造体情報があるからこそ、ポインタのキャストが不整合になっていないかを確実に調べられる。 -配列アクセスについてはデフォルトではバウンドチェックが毎回入る。 -32bitのint域を8bitの char [4] でキャストしてアクセスするなどの方法は全て例外になる。それがやりたいのなら32bitのintをレジスタにロードして、シフトでしかるべき値を得るべきである。 --これによってエンディアンに依存しなくなる。 --逆に char [] に対して、intでアクセスして4倍速にする技も使えない。 --そういう方法で高速化したいのなら「ネイティブコード混在」で好きなようにすればいい。 --性能よりもエンディアンに依存しないことを重視するのでここは譲れない。 -アドレッシング記述はこんな感じになる。 --MOV REG12,AREG04.abc.def --MOV AREG08,AREG07.ary[REG3+2].adr --LEA AREG05,AREG07.ary[REG3+2] --アドレスレジスタの後に構造体のメンバ名を書く。そしてアドレッシングの中に配列アクセスが1つまでなら含められる。そして配列の添え字については定数項・データレジスタ項の2つが許される。データレジスタに対するスケール要素はないがC言語のポインタと同様に添え字が1変わるごとにアドレスが4とか12とか増えていくようになっている。 --C言語をもっと正確に模倣するのなら AREG04->abc.def になるべきなのだが、ここは細かいことは気にせずに.で記述することにする。 --バイトコード的にはメンバ名をそのまま入れるのは非効率なので、メンバIDみたいなものを入れる。添え字がある場合は、添え字までのメンバIDと、添え字のレジスタ番号(適当な常に0の定数レジスタを指定するとこの項が省略されたとみなされる)と、添え字の定数項と、添え字以降のメンバIDが並ぶ。これらはもちろん全てhh4エンコードされる。 --アクセスしたいデータに到達するためには2つ以上の添え字が必要なら、LEAなどを用いて添え字を一つずつ解決していく。 -mallocの際に構造体が記録されるのと同様に、スタックも構造体を記録しなければいけない。だから気軽にスタックポインタを増減させるだけではダメで、それと同時に登録情報を書き換えなければいけない。つまりオーバーヘッドは大きい。 --こういう仕様なのでお気軽にPUSH/POPするのではなくて、関数のスタックフレーム内にしかるべき領域をちゃんと用意しておいて、そこへストア・そこからロードというのが基本になる。 ** 構造体のメンバID -(書き途中) ** 仮想記憶 -gg02では、メモリがあまり十分ではない環境などでは、メモリ内の構造体がHDDなどにスワップアウトされる。そういうことをOSが自由にしてよい。またスワップアウトまではいかないにしても、デフラグ的に構造体の再配置をすることはありうる。 -こういうことが可能なように、レジスタ上、メモリ上でポインタは完全に管理されている。またこの方式ではガーベージコレクションの実装も容易に思われるが、Kはガーベージコレクションが好きではないので意図したものではない。 --メモリリークを探すこともおそらく容易だろう。 -(書き途中)(セグメンテーション、ページングの代わりなどの説明) ** 考察 -(書き途中) * こめんと欄 #comment
タイムスタンプを変更しない
* 第三世代OSASKの仮想CPUの仕様(2) -(by K, 2013.03.09) --(osask.netに書こうと思ったんだけどパスワードを忘れて新規ページが作れない。メモを見つけるまでこっちに書いておく) -今回はメモリアクセスに関する話に限定 --これは結構重要なので、たくさん書くことがある。 --普通のCPUとはかなり異なる。 --そしてCLEとの違いが大きいのもここかもしれない。 ** 基本的な仕組み -アドレスレジスタは、必ずなんらかの構造体のポインタが入る(もしくはNULL)。プログラム上ではそれは一時的に void * でキャストされてそのように扱われるかもしれないけど、それとは無関係にアドレスレジスタのさす先は、何らかの構造体がなければいけない。 -ポインタのキャストは認めるが、メモリ上に展開されている構造体とマッチしないようなキャストは許さない。 -これらを言語レベルではなく、仮想機械語レベルで保証する。 -mallocの際には構造体を指定しなければならず、メモリ確保成功の場合、それはOS側にも登録される。つまりmallocは領域のサイズだけではなく、領域の構造体情報も含めて記録している。 --この構造体情報があるからこそ、ポインタのキャストが不整合になっていないかを確実に調べられる。 -配列アクセスについてはデフォルトではバウンドチェックが毎回入る。 -32bitのint域を8bitの char [4] でキャストしてアクセスするなどの方法は全て例外になる。それがやりたいのなら32bitのintをレジスタにロードして、シフトでしかるべき値を得るべきである。 --これによってエンディアンに依存しなくなる。 --逆に char [] に対して、intでアクセスして4倍速にする技も使えない。 --そういう方法で高速化したいのなら「ネイティブコード混在」で好きなようにすればいい。 --性能よりもエンディアンに依存しないことを重視するのでここは譲れない。 -アドレッシング記述はこんな感じになる。 --MOV REG12,AREG04.abc.def --MOV AREG08,AREG07.ary[REG3+2].adr --LEA AREG05,AREG07.ary[REG3+2] --アドレスレジスタの後に構造体のメンバ名を書く。そしてアドレッシングの中に配列アクセスが1つまでなら含められる。そして配列の添え字については定数項・データレジスタ項の2つが許される。データレジスタに対するスケール要素はないがC言語のポインタと同様に添え字が1変わるごとにアドレスが4とか12とか増えていくようになっている。 --C言語をもっと正確に模倣するのなら AREG04->abc.def になるべきなのだが、ここは細かいことは気にせずに.で記述することにする。 --バイトコード的にはメンバ名をそのまま入れるのは非効率なので、メンバIDみたいなものを入れる。添え字がある場合は、添え字までのメンバIDと、添え字のレジスタ番号(適当な常に0の定数レジスタを指定するとこの項が省略されたとみなされる)と、添え字の定数項と、添え字以降のメンバIDが並ぶ。これらはもちろん全てhh4エンコードされる。 --アクセスしたいデータに到達するためには2つ以上の添え字が必要なら、LEAなどを用いて添え字を一つずつ解決していく。 -mallocの際に構造体が記録されるのと同様に、スタックも構造体を記録しなければいけない。だから気軽にスタックポインタを増減させるだけではダメで、それと同時に登録情報を書き換えなければいけない。つまりオーバーヘッドは大きい。 --こういう仕様なのでお気軽にPUSH/POPするのではなくて、関数のスタックフレーム内にしかるべき領域をちゃんと用意しておいて、そこへストア・そこからロードというのが基本になる。 ** 構造体のメンバID -(書き途中) ** 仮想記憶 -gg02では、メモリがあまり十分ではない環境などでは、メモリ内の構造体がHDDなどにスワップアウトされる。そういうことをOSが自由にしてよい。またスワップアウトまではいかないにしても、デフラグ的に構造体の再配置をすることはありうる。 -こういうことが可能なように、レジスタ上、メモリ上でポインタは完全に管理されている。またこの方式ではガーベージコレクションの実装も容易に思われるが、Kはガーベージコレクションが好きではないので意図したものではない。 --メモリリークを探すこともおそらく容易だろう。 -(書き途中)(セグメンテーション、ページングの代わりなどの説明) ** 考察 -(書き途中) * こめんと欄 #comment
テキスト整形のルールを表示する