page0055
の編集
http://osecpu.osask.jp/wiki/?page0055
[
トップ
] [
編集
|
差分
|
バックアップ
|
添付
|
リロード
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
BracketName
FormattingRules
FrontPage
Fulyn
Fulyn-v2
Fulyn_Samples
Help
InterWiki
InterWikiName
InterWikiSandBox
K
KOR_PIT8254
KWVM.NET
Liva
MANA
MenuBar
OSECPU_FPGA
PG_MANA
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
WikiEngines
WikiName
WikiWikiWeb
YukiWiki
hikalium
hikarupsp
hikarupsp_ELCHNOS
hikarupsp_ELCHNOS_IDE
hikarupsp_FrontEndCode
hikarupsp_WebCPU-VM
hikarupsp_WebCPU-VM_internal
hikarupsp_study_hh4
impressions
impressions0000
jpag0000
jpag0001
jpag0002
jpag0003
jpag0004
jpag0005
lambdalice
mandel59
members
memo0000
memo0001
memo0002
memo0003
memo0004
memo0005
memo0006
memo0007
memo0008
memo0009
memo0010
osask
osecpu4android
page0000
page0001
page0002
page0003
page0004
page0005
page0006
page0007
page0008
page0009
page0010
page0011
page0012
page0013
page0014
page0015
page0016
page0017
page0018
page0019
page0020
page0021
page0022
page0023
page0024
page0025
page0026
page0027
page0028
page0029
page0030
page0031
page0032
page0033
page0034
page0035
page0036
page0037
page0038
page0039
page0040
page0041
page0042
page0043
page0044
page0045
page0046
page0047
page0048
page0049
page0050
page0051
page0052
page0053
page0054
page0055
page0056
page0057
page0058
page0059
page0060
page0061
page0062
page0063
page0064
page0065
page0066
page0067
page0068
page0069
page0070
page0071
page0072
page0073
page0074
page0075
page0076
page0077
page0078
page0079
page0080
page0081
page0082
page0083
page0084
page0085
page0086
page0087
page0088
page0089
page0090
page0091
page0092
page0093
page0094
page0095
page0096
page0097
page0098
page0099
page0100
page0101
page0102
page0103
page0104
page0105
page0106
page0107
page0108
page0109
pagenames
populars
seccamp2013
seccamp2014
seccamp2017
ttwilb
ttwilb-asmi
yao
* OSECPUのラベル命令 -(by [[K]], 2013.07.30) ** (0) はじめに -OSECPUのバイトコードにはラベル命令というのがあります。実はこれは非常に奥が深いので、ここで1ページかけて説明しようと思います。 --参考: [[page0043]]の(8) ** (1) ラベル命令は特異な命令 -まず、多くのCPUはこんな命令を持っていません。確かにアセンブラにはたいていラベル定義命令はあります。でもそれは疑似命令であって、対応するCPUの命令はないのです。 -普通の機械語は、分岐先を指定するときに、○○バイト先へ進め、○○バイト前に戻れ、などと書きます。だからラベルなんてなくても分岐先を記述できるのです。実CPUではないJavaでさえ、この仕様になっています。・・・OSECPUがどれほど変わっているか分かるでしょうか。 -そもそもラベル命令をわざわざ書かなければいけないというのは、機能密度の観点では不利です。他のCPUはそんなものを置いておかなくても分岐先を記述できるのですから。・・・にもかかわらず、OSECPUはラベル命令があり、そしてこれを使わなければ分岐できないのです。 ** (2) ラベル命令のメリット -それでもラベル命令があるのは、つまり捨てがたいメリットがあるからです。 -ラベル命令があって、分岐先に必ずこれを指定するということは、逆に言えばここ以外の場所には分岐しないということです。この情報はJITコンパイラにはとても助けになります。しかしまあこんなものはJITコンパイラのパスを増やせば同等のことができるのではありますが。 -ラベル命令方式だと、命令の区切り以外の中途半端なところへ分岐するという可能性は確実に完全に排除できます。 -ラベル番号だと、結果的に少ないバイト数で分岐先を表現できる可能性があります。いうなれば、ショートブランチが遠くまで届く、という感じです。これは有利です。先ほどは機能密度の観点から不利だと書きましたが、これを加味すると、不利じゃないかもしれません。 -そして最後ですが、実はラベル命令は「分岐先を示すためだけの、何もしない命令」ではないのです。何かするのです。この説明を以下でしようと思います。 ** (3) 無限ループ対策 -[[seccamp2013]]の(6)のPDFの「OSECPUのセキュアの仕組み #07」のところで、OSECPUには無限ループ対策があると書きました。そして OSECPUでは、分岐命令を実行するたびに、分岐回数カウンタという内部変数が+1されます。 -とも書きました。 -この説明だと、いかにもJMP命令に細工をするように見えるかもしれませんが、実際は細工されるのはラベル命令の方です。つまりラベル命令は分岐回数カウンタをカウントアップするコードに変換されるのです。 -ここで、なぜJMP命令ではなくてラベル命令の方に細工をするのかを説明します。これは単純で、JMP命令の個数はラベル命令の個数よりも多いからです(等しい場合もあり得ますが)。だったら細工する数が少ないほうがいいです。どっちにいれても結果は大差ないです。 -なお、PDFにも書いていますが、16命令以上、ラベル命令以外が連続した場合は、そこにも強制的に分岐回数カウンタ++のコードを入れます。 ** (4) OSECPUにおける割り込み処理 -ちょうどいい機会なので、OSECPUにおける割り込み処理についてもついでに書きたいと思います。 -OSECPUにも割り込みの仕組みはありますが、一般的な割り込み処理とは異なり、いつどこで割りこまれるかわからない、というものではありません。ラベル命令のところで割りこまれます。 -なぜか?・・・それは割り込み処理が終了した後に、元の処理に戻らないといけないからです。戻るためにはラベルが必要です。だから他のところで割り込むわけにはいかないのです。 -OSECPUには割り込み禁止命令(CLI)とか、割り込み許可命令(STI)はありません。ラベル命令さえ書かなければ割りこまれないからです。またラベル命令には何とオプションコードがあって、このオプションコードによって、どの程度の割り込み処理を許容するのかを指定することができます。 -OSECPUは非常にレジスタが多く、タスク切り替えのコストは相当なものになる可能性があります。それに対して、このラベル命令のところで割り込みやタスク切り替えが発生するという仕様は、相性がいいです。というのは、アプリは処理が一段落したところでタスクスイッチを受けれればいいからです。これならすべてのレジスタを保存する必要はないでしょう。 -平たく言えば、タスク切り替えを受け入れられるラベル命令は、レジスタを破壊する命令なのです。たとえば「R30~R3F, P30~P3Fの値は破壊されます」という仕様になるかもしれません。これはつまり、タスクスイッチに際して、これらのレジスタを保存していないということでもあります。 -この仕様は結局、割り込み要求が来て待機状態になったら内部のフラグを1にして、ラベル命令のところでこのフラグをチェックしてCALLやタスク切り替えしているだけです。つまりハードウェアの割り込み機能を一切利用していません。だから割り込み機能を持っていないCPUへもOSECPUは移植可能なのです。 -またタスク切り替えを許容するラベル命令が長い間来なかったら、それはセキュリティ例外です。長い間かどうかを決める基準は、もちろん分岐回数カウンタを使います。 ** (5) そのほか -http://nerry.hatenablog.com/entry/2013/07/30/203428 によると、neriさんの意見としては、ラベル命令は機能密度的に有用で、アプリもJITコンパイラも小さくなるそうです。なるほどー。 ** (6) 2013.08.05 追記 -ラベル命令がなくてもJITコンパイラのパスを増やせば何とかなると言いましたが、大きな間違いでした。間接ジャンプのジャンプ先を推測するのは、JITコンパイラのパスを増やしても容易には解決しません。相当がんばるかあきらめないといけません。 --このことを[[page0060]]を書くまですっかり忘れていました。 -となると、ラベル命令は重要です! * こめんと欄 #comment
タイムスタンプを変更しない
* OSECPUのラベル命令 -(by [[K]], 2013.07.30) ** (0) はじめに -OSECPUのバイトコードにはラベル命令というのがあります。実はこれは非常に奥が深いので、ここで1ページかけて説明しようと思います。 --参考: [[page0043]]の(8) ** (1) ラベル命令は特異な命令 -まず、多くのCPUはこんな命令を持っていません。確かにアセンブラにはたいていラベル定義命令はあります。でもそれは疑似命令であって、対応するCPUの命令はないのです。 -普通の機械語は、分岐先を指定するときに、○○バイト先へ進め、○○バイト前に戻れ、などと書きます。だからラベルなんてなくても分岐先を記述できるのです。実CPUではないJavaでさえ、この仕様になっています。・・・OSECPUがどれほど変わっているか分かるでしょうか。 -そもそもラベル命令をわざわざ書かなければいけないというのは、機能密度の観点では不利です。他のCPUはそんなものを置いておかなくても分岐先を記述できるのですから。・・・にもかかわらず、OSECPUはラベル命令があり、そしてこれを使わなければ分岐できないのです。 ** (2) ラベル命令のメリット -それでもラベル命令があるのは、つまり捨てがたいメリットがあるからです。 -ラベル命令があって、分岐先に必ずこれを指定するということは、逆に言えばここ以外の場所には分岐しないということです。この情報はJITコンパイラにはとても助けになります。しかしまあこんなものはJITコンパイラのパスを増やせば同等のことができるのではありますが。 -ラベル命令方式だと、命令の区切り以外の中途半端なところへ分岐するという可能性は確実に完全に排除できます。 -ラベル番号だと、結果的に少ないバイト数で分岐先を表現できる可能性があります。いうなれば、ショートブランチが遠くまで届く、という感じです。これは有利です。先ほどは機能密度の観点から不利だと書きましたが、これを加味すると、不利じゃないかもしれません。 -そして最後ですが、実はラベル命令は「分岐先を示すためだけの、何もしない命令」ではないのです。何かするのです。この説明を以下でしようと思います。 ** (3) 無限ループ対策 -[[seccamp2013]]の(6)のPDFの「OSECPUのセキュアの仕組み #07」のところで、OSECPUには無限ループ対策があると書きました。そして OSECPUでは、分岐命令を実行するたびに、分岐回数カウンタという内部変数が+1されます。 -とも書きました。 -この説明だと、いかにもJMP命令に細工をするように見えるかもしれませんが、実際は細工されるのはラベル命令の方です。つまりラベル命令は分岐回数カウンタをカウントアップするコードに変換されるのです。 -ここで、なぜJMP命令ではなくてラベル命令の方に細工をするのかを説明します。これは単純で、JMP命令の個数はラベル命令の個数よりも多いからです(等しい場合もあり得ますが)。だったら細工する数が少ないほうがいいです。どっちにいれても結果は大差ないです。 -なお、PDFにも書いていますが、16命令以上、ラベル命令以外が連続した場合は、そこにも強制的に分岐回数カウンタ++のコードを入れます。 ** (4) OSECPUにおける割り込み処理 -ちょうどいい機会なので、OSECPUにおける割り込み処理についてもついでに書きたいと思います。 -OSECPUにも割り込みの仕組みはありますが、一般的な割り込み処理とは異なり、いつどこで割りこまれるかわからない、というものではありません。ラベル命令のところで割りこまれます。 -なぜか?・・・それは割り込み処理が終了した後に、元の処理に戻らないといけないからです。戻るためにはラベルが必要です。だから他のところで割り込むわけにはいかないのです。 -OSECPUには割り込み禁止命令(CLI)とか、割り込み許可命令(STI)はありません。ラベル命令さえ書かなければ割りこまれないからです。またラベル命令には何とオプションコードがあって、このオプションコードによって、どの程度の割り込み処理を許容するのかを指定することができます。 -OSECPUは非常にレジスタが多く、タスク切り替えのコストは相当なものになる可能性があります。それに対して、このラベル命令のところで割り込みやタスク切り替えが発生するという仕様は、相性がいいです。というのは、アプリは処理が一段落したところでタスクスイッチを受けれればいいからです。これならすべてのレジスタを保存する必要はないでしょう。 -平たく言えば、タスク切り替えを受け入れられるラベル命令は、レジスタを破壊する命令なのです。たとえば「R30~R3F, P30~P3Fの値は破壊されます」という仕様になるかもしれません。これはつまり、タスクスイッチに際して、これらのレジスタを保存していないということでもあります。 -この仕様は結局、割り込み要求が来て待機状態になったら内部のフラグを1にして、ラベル命令のところでこのフラグをチェックしてCALLやタスク切り替えしているだけです。つまりハードウェアの割り込み機能を一切利用していません。だから割り込み機能を持っていないCPUへもOSECPUは移植可能なのです。 -またタスク切り替えを許容するラベル命令が長い間来なかったら、それはセキュリティ例外です。長い間かどうかを決める基準は、もちろん分岐回数カウンタを使います。 ** (5) そのほか -http://nerry.hatenablog.com/entry/2013/07/30/203428 によると、neriさんの意見としては、ラベル命令は機能密度的に有用で、アプリもJITコンパイラも小さくなるそうです。なるほどー。 ** (6) 2013.08.05 追記 -ラベル命令がなくてもJITコンパイラのパスを増やせば何とかなると言いましたが、大きな間違いでした。間接ジャンプのジャンプ先を推測するのは、JITコンパイラのパスを増やしても容易には解決しません。相当がんばるかあきらめないといけません。 --このことを[[page0060]]を書くまですっかり忘れていました。 -となると、ラベル命令は重要です! * こめんと欄 #comment
テキスト整形のルールを表示する