やぁみんな、ビリーだよ。
今年もよろしくね!
さて、今日はビリー宛てにもらった質問を紹介しよう。
読者からの質問
PC(Program Counter)レジスタとLR(リンクレジスタ)について教えていただけませんか?
ビリーからの回答
質問ありがとう。
スタックってなあに?(1)で、SPレジスタやFPレジスタの説明をしたんだけど、これを読んでくれての質問みたいだね。PC(Program Counter)レジスタとLR(リンクレジスタ)、それぞれについて、説明するね。
PC(Program Counter)レジスタ
PC(Program Counter)レジスタは、現在CPUがプログラムのどこを実行中であるかを格納しておくレジスタだ。基本的にはどんなCPUにでも存在するよ。
CPUは、メモリ上(RAMやフラッシュメモリ等)に置かれたプログラムの機械語コード(アセンブラ命令)を読み出して実行するのだけど、PCレジスタには実行中の機械語コードが置かれているメモリアドレスが入っているんだ。
このレジスタは、通常はプログラムから書き換えることはせず、アセンブラの分岐命令(C言語でサブルーチン呼び出しを行った場合など)が実行されると、分岐先のアドレスに書き換えられるよ。
例えば以下のような C言語のコードで、
testA 関数のコードはメモリ中の 0x5000番地
testB 関数のコードはメモリ中の 0x5700番地
にあったとする。
余談だけど、これらの関数のアドレス(番地)はプログラムのコンパイル・リンクを行う際のリンク実行時に決まるよ。
testA 関数のアセンブラコードは、例えば以下のようになる。
JSRはtestB(=0x5700)番地に分岐する、というアセンブラ命令。JSRという名称はCPUによって異なるからね。
testAはメモリ中の0x5000番地にあるけど、(省略1)のコードがあるから、JSR命令部分のコードは0x5048 番地ぐらいにあると仮定しよう。
JSR命令を実行する時点で、PCレジスタには0x5048が入っているよ。ここでJSR命令が実行されると、PCの現在値(0x5048)をどこかに覚えておいて(詳しくは後述)、PCには0x5700が代入され0x5700番地のtestB関数が実行される、という動作となるんだ。
LR(LinkRegister)レジスタ
LR(リンクレジスタ)は、分岐命令(サブルーチン呼び出し)が行われたときに、サブルーチン終了後に呼び出し元に戻ってこられるよう、現在の PC 値(正確には、現在の PC 値の次の命令のアドレス)を覚えておくためのものだよ。
このレジスタはPCレジスタとは異なり、すべてのCPUにあるわけじゃないんだ。例えばARMやPowerPC系のCPUには存在するけど、Intel x86系やSH系のCPUには存在しないよ(※2月7日修正:SHシリーズには同じ機能のPR(プロシジャレジスタ)をもつものがあります)。
PCレジスタの説明で、「JSR命令を実行するときに、PCの現在値をどこかに覚えておいて、」というのが出てきだけど、この「どこか」がリンクレジスタになるわけなんだ。
リンクレジスタが無いx86などのCPUでは、呼び出し元のPC値をスタックに積んでおき、呼び出し元に戻るときにスタックか PC値を復元しているよ。
ではリンクレジスタが存在するCPUで、サブルーチン呼び出しが二重三重になった場合はどうするのか、リンクレジスタは1個しかないじゃん、という疑問が出て来るけど、こんな場合はやっぱりスタックが使われるんだ。
今回は質問に対する回答ということで、PCレジスタとリンクレジスタの説明をしたけど、CPUレジスタについては、一度ちゃんと整理して説明したほうがいいかもしれないね。アセンブラでプログラムを書くことはあまりないかもしれないけれど、C言語と併用する場合なんかは、レジスタをちゃんと理解しておかないといけない。レジスタはCPUによって違うから、一般的な説明は難しいんだけどね。
-
- 第1回 組込みシステムのこれから
- 第2回 IoTの成功はセキュリティ次第
- 第3回 組込みでもGPUやFPGAと早めに親しんでおこう
- 第4回 電子産業の紅白歌合戦、CEATECで垣間見えた未来
- 第5回 小口開発案件の集合市場、IoTの歩き方(上)
- 第6回 小口開発案件の集合市場、IoTの歩き方(下)
- 第7回 徹底予習:AI時代の組込みシステム開発のお仕事
- 第8回 いまどきのセンサー(上):ありのままの状態を知る
- 第9回 いまどきのセンサー(下):データを賢く取捨選択する
- 第10回 組込みブロックチェーンの衝撃(上)
- 第11回 組込みブロックチェーンの衝撃(下)
- 第12回 エネルギーハーベスティングの使い所、使い方
- 第13回 「人を育てる」から「道具を育てる」へ、農業から学ぶAI有効活用法
- 第14回 CPS時代に組込みシステム開発に求められることとは
- 第15回 次世代車のE/Eアーキテクチャに見る組込みの進む道
- 第16回 RISC-Vが拓く専用プロセッサの時代
- 第17回 振動計測の大進化で、熟練エンジニアのスキルを広く身近に
-
- 零の巻:組込みというお仕事
- 壱の巻:2進数と16進数を覚えよう!
- 弐の巻:割り込みとポーリング
- 参の巻:printf()が使えない?
- 四の巻:これにもIntelが入ってるの?
- 五の巻:Endianってなに?
- 六の巻:マルチタスクとは
- 七の巻:スタックってなあに?(1)
- 七の巻:スタックってなあに?(2)
- 八の巻:メモリを壊してみましょう
- 九の巻:コードが消える?~最適化の罠~
- 拾の巻:例外が発生しました
- 拾壱の巻:コードサイズを聞かれたら
- 拾弐の巻:キャッシュは諸刃の剣
- 拾参の巻:デバイスにアクセスするには
- 拾四の巻:セキュリティってなに?(1)
- 拾四の巻:セキュリティってなに?(2)
- 拾四の巻:セキュリティってなに?(3)
- 拾五の巻 :DMA対応と言われたら(1)
- 拾五の巻 :DMA対応と言われたら(2)
- 拾六の巻:ヒープとスタック
- 拾七の巻:フラグメンテーション
- 拾八の巻:CPU起動とブートローダ
- 拾九の巻:kmとKByteの「kとK」
- ビリーへの質問:DMAとキャッシュの関係
- ビリーへの質問:スタックオーバーフローについて
- ビリーへの質問:CPUレジスタについて