💦 アセンブリ入門
レジスタはアセンブリ言語を理解するために重要な概念です。
高級言語を使用する際も、頭に入れておくと良いかもしれません。
関連記事
レジスタとは何か?
レジスタとはプロセッサ内の小さなメモリ領域のことで、高速にアクセスでき、データやアドレスを一時的に格納するために使用されます。
レジスタは他のプログラミング言語の変数のようなものに該当します が、所々高級言語とは仕様が異なります。
- レジスタは変数なようなものでありながらハードウェアの一部であり、変数の数も制限があります(x86-64では汎用レジスタは16個のみ)
- 一般的な高級言語の変数データはRAMに保存されますが、レジスタはCPU内部のリソースです。
- 一般的な高級言語には変数は種類がありませんが、一般的なレジスタはすでに用意されているものを使わなければならず、演算用の汎用レジスタ、アドレスを格納するためのインデックスレジスタ、フラグを格納するためのフラグレジスタなどの種類があります。
レジスタは 1+2を計算する際の、 1 と 2 を記憶する場所と考えるのが良さそうです。
Note:レジスタはメモリではない!
勘違いしてましたが、メモリとレジスタは異なります。
- レジスタ : アセンブリ言語がアクセスできる、計算のために覚えておくことができるCPU内部の記憶領域。ADD命令,SUB命令などからアクセス可能。
- メモリ : アセンブリ言語はアクセスできるが、制限がある。(MOV命令でメモリからレジスタに移動させてから、ADD命令,SUB命令で計算させる)
- スタック領域 : FIFO方式のメモリ領域。関数の呼び出しやローカル変数の管理に使用されます。
- ヒープ領域 : プログラムの実行中に動的に確保されるメモリ領域です。
- データセグメント : 静的変数やグローバル変数などが保存されます。
- コードセグメント : この領域には、プログラムの実行命令や定数などが含まれます。
レジスタ一覧
注意 : この章はレジスタの一覧を解説するものですが、正確性に欠く表現があるかもしれません。
レジスタの種類は以下の通り。
レジスタごとに役割が定まっているというのが重要かもしれません。
| レジスタ名 | 用途 | 16ビット | 32ビット | 64ビット |
|---|---|---|---|---|
| AX | 累積レジスタ(一般的な演算) | AX | EAX | RAX |
| BX | ベースレジスタ(アドレス保持など) | BX | EBX | RBX |
| CX | カウンタレジスタ(ループカウンタなど) | CX | ECX | RCX |
| DX | データレジスタ(演算、I/O操作) | DX | EDX | RDX |
| SI | ソースインデックス(データコピー操作のソース) | SI | ESI | RSI |
| DI | ディスティネーションインデックス(データコピー操作のディスティネーション) | DI | EDI | RDI |
| BP | ベースポインタ(スタックフレームの基準) | BP | EBP | RBP |
| SP | スタックポインタ(スタックの先頭を指す) | SP | ESP | RSP |
以下、上の表の規則性の話。
レジスタの種類は基本8種類。
- AX
- BX
- CX
- DX
- SI
- DI
- BP
- SP
それぞれのアルファベットがつくかどうかでサイズが変わる(AXを例とする)
-
AX: サイズは16bit -
EAX: サイズは32bit -
RAX: サイズは64bit
最近のCPUは大体64bitなので、R始まりの変数が参照されがちです。
レジスタへの代入方法:mov
代入にはmov命令を使用する。
以下のケースでは
raxに0x1を代入している。
mov rax 0x1
レジスタの種類はCPUアーキテクチャごとに異なる
前の表で紹介したレジスタは x86系CPUの基本レジスタです。
しかしCPUアーキテクチャによってレジスタ構成は変わります。
| CPUアーキテクチャ | 特徴 |
|---|---|
| x86 | 歴史が長く、特殊用途レジスタが多い |
| x86-64 | x86を64bit拡張したもの |
| ARM | 汎用レジスタが多くシンプル |
| RISC-V | 非常にシンプルな設計 |
そもそもCPUアーキテクチャは、OSごとに異なります。
| OS | 主なCPU |
|---|---|
| Windows | x86-64 |
| Linux | x86-64 / ARM |
| macOS | ARM(Apple Silicon) |
OSごとに主に使われるCPUアーキテクチャが異なり、
CPUアーキテクチャによってレジスタ構成や命令セットが変わります。
そのため CPUアーキテクチャが変わると、アセンブリ言語は基本的に書き直しになります。
結果として OSが変わるとアセンブリコードを書き直す必要があるケースもあります。
(OSが同じでも書き直しになるケースも : Intel Mac(昔のMac) -> Apple Silicon Mac(現在のMac) )
そのために、この課題を解決するため 昔の人たちが、CPUアーキテクチャごとに対応したアセンブリを作成するように 高級言語を生み出した と考えます。
CPUごとにアセンブリが違う
↓
移植が大変
↓
共通の高級言語を作る
↓
コンパイラがCPUごとに変換
まとめ
レジスタは CPU内部にある高速な記憶領域であり、アセンブリ言語ではデータやアドレスを一時的に保持するために使用されます。
高級言語でいう変数に近い役割を持ちますが、CPUのハードウェア資源であるため数が限られている点が特徴です。
先人たちが高級言語のコンパイラを作成したときは各CPUアーキテクチャに合わせるためかなり苦労したのではないかな〜と思いを馳せました。
(ここは想像です...)
