問題タブ [self-modifying]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
ruby - Ruby の自己変更コードのリロード
前の質問に続いて、正確に何が欲しいかについて、より正確に、難読化を減らしてください。「ATP」、「アデノシン」、「デオキシシチジン」など、すべての化学物質と反応の名前を大文字にすることを決定した化学パッケージを作成しました。これにより、次のように書くことができました。
ここで、ATP を使用して GDP をリン酸化する場合、触媒定数を持つ酵素 NDPK を使用します。
、これは次のように書きたいです:
私はちょうど書くことができます:
でもぬるすぎる気がする。心に留めながら、どのようreactant_1
に、 2回繰り返しますか。簡単な解決策は次のとおりです。reactant_2
ATP
GDP
そして、との濃度を、としてinstance_eval
定義するコンテキスト内のレート検出ブロック。これは非常に近いですが、私が望んでいるものとはまったく異なり、それは私から天国を怒らせます. ブロック内で使用されている化学物質を見つけるために使用することもできます。_ATP
_GDP
ATP
GDP
RubyVM
これを解析することで、 と の中にどんな名前が入っているかがわかり_ATP
ます_GDP
。しかし、私が言ったように、頑固さから、私は醜いと思い_ATP
ます_GDP
。化学者は濃度に括弧を使用するため、単にATP
, GDP
, またはおそらく[ATP]
,と言いたい. [GDP]
これが、遠藤祐介が制約付きコーディングと呼ぶものであることは知っています。私の質問は、これら 2 つの望ましい構文のいずれかを打ち負かすことができるかということです。たとえば、クロージャがlambda { ATP * GDP * NDPK_constant }
あり、それを逆アセンブルすると、次のようになります。
、 の 7 行目、getconstant
10 行目に表示されていることがわかります。ブロックの外では定数にインスタンスが含まれていますが、ブロック内では ATP と GDP の濃度を参照するようにします。定数自体が異なる意味を持つ環境でブロックを評価する方法が見つかりませんでした (つまり、実行時に汚いトリックを使用して一時的に定数を書き換えたい場合を除きます)。私が切望しているのは、このRubyVMコード命令をたとえば. 、そして例えば。環境でのこの閉鎖は...難しい質問をしていることを知っています、もう一度申し訳ありません...:ATP
:GDP
ATP
GDP
ChemicalSpecies
getconstant :ATP
send :_ATP, 0, nil, 24, <ic:0>
instance_eval
_ATP
ATP.concentration
2 番目のオプション については[ATP]
、[GDP]
ブロック内のみで何らかの新しい配列作成フックをアクティブにする必要があるため、要素が 1 つしかない場合、つまり がありChemicalSpecies
、配列オブジェクトの代わりにその濃度が返されます。不可能ではないにしても、これは同じくらい難しいと思います。
lisp - 同性愛のレベル
これは私の前の質問へのフォローアップです。私は、Lisp コードがフォン ノイマン アーキテクチャ上のマシン コードと同じくらいホモイコニックであるとは確信していません。どちらの場合もコードがデータとして表現されることは明らかですが、Lisp よりも機械語でこのプロパティをはるかに自由に利用できることも明らかです。
マシン コードをいじくり回すと、コードの自己変更が非常に簡単になり、多くの場合偶然に (私の経験では) 面白い結果が得られます。単純な「0 ~ 15 の数字を出力する」プログラムを作成しているときに、ポインターの 1 つに「off by one」エラーが発生することがあります。レジスタ 1 にあるものを、次の命令を含むメモリ内のアドレスに誤ってダンプしてしまい、代わりにランダムな命令が実行されます。(ある種の「goto」の場合は常に素晴らしいです。神はそれがどこに行き着くのか、その後何をするのかを知っています)
コードとデータの間に分離はありません。すべてが同時に命令 (単なる NOP であっても) であり、ポインタであり、昔ながらの数値でもあります。また、目の前でコードが変更される可能性があります。
私が頭を悩ませてきた Lisp のシナリオを教えてください。次のプログラムがあるとします。
ここで、私がやりたいことは、このプログラムに、* を + に変更し、<= を >= に変更し、そこのどこかに (+ 1 2 3) を貼り付けて、一般的に関数を盗聴する Lisp コードを追加することです。上。そして、結果として生じる絶対的な混乱をプログラムに実行させたいのです。
重要なポイント: サンプル コードに致命的なエラーがない限り、変更できるのはその-– More code goes here –-
部分だけです。上に表示されているのはコードです。リスト全体を引用して変数に格納して、操作して同じ名前の別の関数として吐き出すことができるようにしたくありません。factorial をまったく別のものとして標準的に再定義したくありません。マシンコードのように、画面に表示されているコードが目の前で変化するようにしたいのです。
これが不可能/不合理な要求である場合、ホモイコニシティは言語が持っている、または持っていない個別の特性ではなく、スペクトルであり、Lisp は最先端ではないという考えが私の心の中でさらに固まるだけです。(あるいは、Lisp はホモイコニックであり、マシンコード風の自己変更を説明する他の用語を探しています)
c - 自己変更コードを使用した x86 での古い命令フェッチの観察
Intel のマニュアルから、命令をメモリに書き込むことは可能であると言われ、読みましたが、命令プリフェッチ キューは古い命令を既にフェッチしており、それらの古い命令を実行します。私はこの行動を観察できませんでした。私の方法論は以下の通りです。
Intel ソフトウェア開発マニュアルには、セクション 11.6 から次のように記載されています。
プロセッサに現在キャッシュされているコード セグメントのメモリ位置への書き込みにより、関連するキャッシュ ラインが無効になります。このチェックは、命令の物理アドレスに基づいています。さらに、P6 ファミリおよび Pentium プロセッサは、コード セグメントへの書き込みによって、実行のためにプリフェッチされた命令が変更される可能性があるかどうかをチェックします。書き込みがプリフェッチされた命令に影響を与える場合、プリフェッチ キューは無効になります。この後者のチェックは、命令の線形アドレスに基づいています。
したがって、古い命令を実行したい場合は、2 つの異なる線形アドレスが同じ物理ページを参照する必要があるようです。そのため、ファイルを 2 つの異なるアドレスにメモリ マップします。
変更したい命令へのポインタである単一の引数を取るアセンブリ関数があります。
C では、コードをメモリ マップド ファイルにコピーします。関数は linear address から呼び出しますが、コード変更のターゲットとしてa1
ポインターを渡します。a2
CPU が変更されたコードを取得した場合、val==1 です。それ以外の場合、古い命令が実行された場合 (2 つの nop)、val==0 です。
これを 1.7GHz Intel Core i5 (2011 macbook air) と Intel(R) Xeon(R) CPU X3460 @ 2.80GHz で実行しました。ただし、毎回、CPU が常に新しい命令に気付いていることを示す val==1 が表示されます。
私が観察したい行動を経験した人はいますか?私の推論は正しいですか?P6 および Pentium プロセッサについて言及しているマニュアルと、私の Core i5 プロセッサについて言及していないことについて、私は少し混乱しています。おそらく、CPU が命令プリフェッチ キューをフラッシュする原因となる何か他のことが起こっているのでしょうか? どんな洞察も非常に役に立ちます!
c - Cの自己変更コードで関数の参照が失われるのはなぜですか?
Cで自己変更コードを作成しているときに関数を逆参照する必要がある理由を理解しようとしています.
このように機能しますが、その理由を知りたいです!
これが私が扱っていたものの例です: http://nmav.gnutls.org/2011/12/self-modifying-code-using-gcc.html
私はブログの男に尋ねましたが、彼は答えませんでした:(