質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

Q&A

解決済

2回答

282閲覧

CPUのレジスタ間で、レジスタを上書き•変更するのではなく、コピーするのは何故ですか?

DeepRoastBeans

総合スコア79

CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

0グッド

0クリップ

投稿2024/01/20 04:06

実現したいこと

  • コンパイラ(プログラミング言語)を作りたくアセンブラを勉強を始めました。

質問

アセンブラのソースコードを見ると、汎用レジスタ間でのmovが沢山に出てきますが、なぜレジスタ間でコピーする必要があるのでしょうか?単純にレジスタの値の上書きや変更はできないのでしょうか?

ソースコード例(ARM64)

.text .global _start _start: mov x2, #13 // x2 length adr x1, msg // x1 string address mov x0, #1 // x0 stdout mov x8, #64 svc #0 // sys_write mov x0, xzr mov x8, #93 svc #0 // exit msg: .asciz "hello, world\n"

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matukeso

2024/01/20 04:52

その例示ソースにはレジスタ間でのコピーは一個もないように見受けられますが。(zxrは微妙)
ikedas

2024/01/20 05:16

mov命令は汎用レジスタの値を上書き・変更しますが、上書きや変更ではない「コピー」というのはどういうことを指しているのでしょうか。
DeepRoastBeans

2024/01/20 06:59

> mov命令は汎用レジスタの値を上書き・変更します レジスタの値を上書き・変更するって意味なんですね。ありがとうございます。 >上書きや変更ではない「コピー」というのはどういうことを指しているのでしょうか。 質問の意図としては、レジスタの値を変更できるのであれば、わざわざレジスタ間でコピーせずに該当のレジスタの値だけ更新した方が効率的かと思ったのですが、レジスタ間でコピーする処理が必要な場面があるってことなんですかね。 いまいち理解せずに質問してしまいすみません。ドキュメントにも「Move (register) copies the value in a source register to the destination register.」とありますね。 https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MOV--register---Move--register---an-alias-of-ORR--shifted-register--
ikedas

2024/01/20 09:54

たとえば、ある変数x、y、z、wに値が入っていて、 (x + y) * (z + w) を計算するようなプログラムを書くとしますね。それをコンパイラで機械語にするとどんな結果になるかを考えてみればいいんじゃないですか。
DeepRoastBeans

2024/01/21 06:06

c言語でコンパイルしたアセンブラを見ると、宣言したタイミングでメモリにstoreし、変数を読み込むタイミングでメモリからロードしていますね。なるほど、Cのコンパイルの中身を見ると、かなり参考になりますね。 ### c #include <stdio.h> int main(void) { int x=1; int y=2; int z=3; int w=4; printf("%d\n", (x+y)*(z+w)); return 0; } ### arm64 stp fp,lr,[sp,#-0x20]! mov fp,sp mov w8,#1 str w8,[sp,#0x10] mov w8,#2 str w8,[sp,#0x14] mov w8,#3 str w8,[sp,#0x18] mov w8,#4 str w8,[sp,#0x1C] ldr w9,[sp,#0x10] ldr w8,[sp,#0x14] add w10,w9,w8 ldr w9,[sp,#0x18] ldr w8,[sp,#0x1C] add w8,w9,w8 mul w1,w10,w8 mov w1,w1 adrp x8,|$SG5195| add x0,x8,PageOffset(|$SG5195|) bl printf mov w0,#0 ldp fp,lr,[sp],#0x20 ret ### 自分が書いたアセンブラ _start: mov x1, #1 mov x2, #2 mov x3, #3 mov x4, #4 add x1, x1, x2 add x3, x3, x4 mul x0, x1, x3 コンパイルに使用したサイト https://gcc.godbolt.org/
ikedas

2024/01/21 06:49

使ったコンパイラがなんなのか分かりませんが、私の手元のARM64 clangの結果とほぼ同じようですね。 最適化オプション (例えば -Os) をつけると生成されるコードが変わります。最適化を考えないで汎用性を大事にすると、アセンブラで直接記述した (完璧に最適化された状態) ときより冗長なコードが生成されるでしょう。
guest

回答2

0

レジスタ間でコピーする処理が必要な場面があるってことなんですかね。

レジスタ間でコピーを行う必要性。
ケース1:レジスタに役割がある場合。
CPUによって、どのレジスタでも同じ事が出来る物もあるが(※注)、多くのCPUでは、「この機能はレジスタAでは出来ないので、その機能が出来るレジスタBにコピーしてから使う」という場合がある。

※注:まるっきり全部同じというCPUは多分ない

ケース2:同じ事が出来ても、処理時間や命令長が違う場合はコピーするかも。しないかも。
例えば、複数のレジスタに同じ値をセットする場合、それぞれセットするより、1つセットして残りはそれをコピーする方が、おそらく速いし命令長も短い。

ケース3:値を変更する場合。
これから値を変更するが、元の値も残しておく必要があるケース。
これは自明。

投稿2024/01/20 07:39

otn

総合スコア84571

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DeepRoastBeans

2024/01/20 07:51

なるほどっすね、ケース1、2の場合などレジスタの機能の理解が必須ってことなんですね。凄い分かりやすい説明ありがとうございます!
guest

0

ベストアンサー

アセンブラのレジスタに限らず、この世のあらゆるプログラミング言語の変数の代入にしても全部コピーですよ。
それでも、なぜコピー?という疑問を持つなら、そういうもんだ、ということで納得しときましょう

投稿2024/01/20 06:51

編集2024/01/20 06:52
y_waiwai

総合スコア87778

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DeepRoastBeans

2024/01/20 07:06

なんか勘違いしていたのかもしれません。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問