パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

むむう」記事へのコメント

  • static char const str[] = "afo";

    str[ 0 ] = 'x';

    とか?
    でも実際に動かしてみると、
    Segmentation fault
    だって。
    • 仰っている意味が(素で)いまいち良く分かりません orz

      けど、とりあえず(ここ大事)ソースに書いてコンパイルしてみたところ
      コンパイラさんは
          警告: 代入が読み込み専用領域で行われました

      で、実行させたら
          セグメンテーション違反です

      ですって。
      • static char const str[] = "afo";

        char *str = "afo";
        としても結果は同じでした。
        コンパイルで警告が出ないところは違いますが。
        # コードとしてタチが悪いものの今回の現象が解りやすいのは後者かも知れない

        で、この "afo" っていう文字列は「文字列定数」なのです。"afo"は"afo"として使わねばならず、"xfo"とは出来ません。もしそういう使い方をしたいなら、
        static char const str[] = "afo";
        char buff[ 4 ];
        strncpy( buff, str, sizeof( buff ) );
        buff[ 0 ] = 'x';
        とします(書き換え可能な領域は別に用意する必要があり
        • まぢ説明だとそんな感じですね~。一つチャチャを入れさせてもらうなら、
          s/よそのプロセス/アクセスに特権が要るリソース/てなもんでしょうか。
          よそのプロセスはそもそも見えないし。
          # マニヤックな記述で文字列定数使うなら*"" = 'x';とかですかね。
          • ご指摘ありがとうございます。
            仰せのとおり、他プロセスのメモリは見えませんね。
            メモリディスクリプタテーブルのエントリが異なるので。
            # 8086→80286→80386の進化ではこのメモリディスクリプタテーブルの辺りが一番面白いと思います。
            • 無理矢理書き込もうとしても、メモリプロテクション様のお怒りを
              買うという意図を達することができそうな気がするんですが
              どうなんでしょう?

              なんとなーくWebを眺めていたら、VxWorksさんがバージョンアップして
              いままで苦手だったメモリプロテクションなどを手がけるようになった
              みたいですね。セミナに行くとサンプルコードが貰えそうな勢いですが、
              会社に転がっている各種の評価用OSで試すことが出来たら面白いかもねー、
              なんて妄想中です。

              日記に書いた
              • というのが、 コレ [srad.jp]なわけですわ。

                それでもって、見えない部分に書くというのが、「他プロセスの持ち物だけど、自分から見えていないと思われる場所にあてずっぽうで書く」 というのであれば、絶対に無理です。
                自分のプロセスのメモリ空間(論理アドレス)にマッピングされていない領域なので。

                というわけで「メモリディスクリプタテーブル」が避けて通れなくなりました。
                # さすがに、コレを直接見たりいじったりする用が無いので、正しく説明できるかどうか怪しいのですが…
                # 間違ってたらバシバシ指摘してください>みなさま

                大雑把に言って、どの論理アドレス
              • IA32では、メモリ空間が何種類かあって、
                        1.セグメント内空間
                        2.リニアアドレス
                        3.物理アドレス
                みたいになってます。
                # 286ではページングできないので2と3は一緒です。

                セグメントは1-2間の変換に使います。なのでセレクタ:オフセットの組で指
                定できるのは2のリニアアドレスです。

                2-3の変換にはページテーブルを用います。具体的にはCR3でページテーブル
                の集合であるページディレクトリの物理アドレスを指定してページテーブル群
                を指定します。んで、このページテーブル群がプロセス空間になります。
                # ページテーブルの指定はページディレクトリでページテーブルのリニアア
                # ドレスを指定します。この辺は厄介でおもしろいところです。

                プロセスを切り替える際にはページテーブル群をまるごと切り替えてしまうの
                で、よそのプロセスの持ちものは文字どおり見えなくなります。もっとも、カ
                ーネルから実メモリが全部見えるようにマッピングすることも多いのでカーネ
                ルによっては絶対に見えないわけでもありません。が、そこは当然触るのには
                特権が必要な領域なわけです。

                で、IA32では、
                        a.セグメントの属性/特権
                        b.空ページ/特権
                の2つの違反ができます。変な表現ですが。

                *"" = 'x';みたいに文字列に書き込むというのはaに違反します。
                *(int*)hoge = 0;はhogeの値によりますが、セグメント違反な場所ならa
                セグメントがOKでページが割り当てられてないところならbの違反ができます。
                親コメント
              • by hix (3507) on 2004年05月11日 17時38分 (#545355) 日記
                昔に文献を読んだ記憶で書いたので、抜けがあったり違ってたりしていました。
                補足ありがとうございます。

                80286と80386でアドレス変換の手順が一つ増えたハズだと思っていたのですが、それがページテーブルだったのですね...思い出してきました。
                # 昔本を読んだ時にも、その辺りの関係がちっとも理解できず、苦労した記憶が…
                # 「ディスクリプタ」とか「ディレクトリ」とか、ファイルシステムで同じ名前を持つ物と概念的な部分で混同してしまったり、
                # アプリケーションで使っているアドレスを物理アドレスに変換してみようとした時に、今見ているテーブルが何のテーブルだか解らなくなったり…

                昔はWin95でその辺りの物をいじったので、今度はLinuxで見てみることにします。
                親コメント
              • 今そのあたりをやってるだけだし。
                親コメント

弘法筆を選ばず、アレゲはキーボードを選ぶ -- アレゲ研究家

処理中...