1: 2007-12-01 (土) 11:47:08 |
2: 2007-12-01 (土) 13:07:41 |
| いろいろと難しいが、とにかくまずは、''アドレスを指定する時には二つのレジスタが必要''と理解しよう。 | | いろいろと難しいが、とにかくまずは、''アドレスを指定する時には二つのレジスタが必要''と理解しよう。 |
| + | |
| + | **なぜ二つ? 普通は一個でしょ?? [#je7bb9b5] |
| + | まったくその通りである。通常のCPUはそういうのが多い。 |
| + | |
| + | ・・・しかし、ちょっとここで仮定してみる。16ビットCPUである8086が''仮に''セグメントなんていうややこしい仕組みを持っていないとしよう。 |
| + | |
| + | よし! メモリを全部読んでみる実験だ! |
| + | |
| + | START: |
| + | MOV BX,0x0000 ;開始する番地 |
| + | MOV CX,0xFFFF ;ループする回数 |
| + | JMP LOOP |
| + | |
| + | FORNEXT: |
| + | MOV AX,[BX] ;BX番地のメモリの内容をAXに読んでみる |
| + | ADD BX,0x0001 ;BXの番地をひとつ増やす |
| + | LOOP FORNEXT ;CXの値をひとつ減らしてFORNEXT部にジャンプ |
| + | |
| + | さぁこれで全部のメモリを読むことはできたよね? |
| + | |
| + | ・・・全部のメモリって、いくつ? ・・・・ |
| + | |
| + | 0x0000番地〜0xFFFF番地まで。0xFFFFバイト。10進数に直すと65,535バイト。これを1024で割り算してKB単位にすると・・・・約64KB・・・えぇぇ!! たった64KB!??? |
| + | |
| + | ''そう!''、セグメントなんてややこしいことを排除するとシンプルになるけど、16ビットでは扱えるメモリが猛烈に小さくなってしまうんです!!! |
| + | |
| + | 参考までに。~ |
| + | 32ビット。16ビットのたった2倍だよね?。上記と同じように計算してみると・・・~ |
| + | 0x00000000番地〜0xFFFFFFFF番地まで。0xFFFFFFFFバイト。10進数に直すと4,294,967,295バイト。これを1024で割り算してKB単位にすると・・・4,194,304KB・・・さらに1024で割り算してMB単位にすると・・・4096MB・・・もういいよね? なんと、4GB!!!~ |
| + | こんなに贅沢に沢山のメモリを使えるので、32ビットの時にはセグメントなんてない。というか、そんなややこしいことしなくてもいいわけ。(注1) |
| + | |
| + | そう。CPUのビット数だけ見ると、たかだか倍なのでたいしたことないように見えるかもしれないけど、16ビットと32ビットじゃ、こんなに巨大な差があるんだ! |
| + | |
| + | |
| + | 「じゃ、全部32ビットにすりゃいいじゃん!」と考える人がいたら多分その人はあまり頭がよくないと思うよ。 |
| + | |
| + | 江戸時代の人に向かって「バカだなぁ。トラック使えばお城なんて簡単に作れるのに」と言っているのと同じだからね。 |
| + | |
| + | |
| + | 8086はたった64KBしか扱えないという制限を何とかしたかった。そのため、''メモリ番地の指定だけは二つの16ビットレジスタを使うようにしてなんとか凌ごう!''という方法を取ったわけ。 |
| + | |
| + | |
| + | メモリの番地を指定する時だけは、 セグメントレジスタ & オフセットレジスタ という、二つのレジスタが使われるようにした。これがセグメントの考え方。 |
| + | |
| + | ***具体的には???? [#k1355799] |
| + | ここに、物理的にメモリを1MB搭載したマシンがあるとする。1MBということは、だいたい0x00000〜0xFFFFFまでメモリが搭載されていることになるよね?。 |
| + | |
| + | |
| + | 例えば、上記の、''セグメントなんてない16ビットCPU''の場合。番地を指定するのもレジスタだよね?。それが16ビットしかないんだから、0x0000〜0xFFFFまでの値しか指定できない。たとえ物理的に何GBメモリを搭載していても・・・。 |
| + | ;このマシンは1MB搭載機だ!0xFFFFFまでメモリが使えるぞ! |
| + | ;さっそく一番最後のメモリを読んでみよう! |
| + | MOV BX,0xFFFFF ;BXに読みたいメモリの番地を代入 |
| + | MOV AX,[BX] ;BX番地のメモリの内容をAXに代入 |
| + | ;わーい! これで1MBの所を読めたぞ! |
| + | これは大間違いでしょ? (^^; |
| + | |
| + | BXは16ビットだもん。0xFFFFFなんて値、桁がないので代入できないよ!(よく見て。5桁あるでしょ?) |
| + | |
| + | |
| + | ここでセグメントレジスタの出番となるわけ。 |
| + | |
| + | |
| + | 上記の間違いプログラムと同じことをしたい場合こうなる。先に見てみて。 |
| + | ;このマシンは1MB搭載機だ!0xFFFFFまでメモリが使えるぞ! |
| + | ;さっそく一番最後のメモリを読んでみよう! |
| + | MOV DS,0xF000 ;セグメントレジスタの一つ、DSにセグメントを |
| + | MOV BX,0xFFFF ;BXに読みたいメモリのオフセット値を |
| + | MOV AX,[DS:BX] ;こんなことすると、0xFFFFF番地を読める! |
| + | ;わーい! これで1MBの所を読めたぞ! |