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

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

新規登録して質問してみよう
ただいま回答率
85.50%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

ARMv7

ARMv7は、ARM命令セットアーキテクチャーVersion 7のことです。

Q&A

解決済

2回答

3268閲覧

[アセンブリ言語]armのロード命令

marny

総合スコア19

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

ARMv7

ARMv7は、ARM命令セットアーキテクチャーVersion 7のことです。

0グッド

0クリップ

投稿2019/01/24 11:14

編集2019/01/24 12:03

いつもお世話になっております。

Armのアセンブリ語のロード命令について質問です。

ldr r4,[r1,#36]

この命令について自分は、「r1に入ってるアドレスに36を足されたアドレスにある命令orデータがr4に入れられる。」というように考えていました。
指しているアドレスr1,#36に格納されていたのは、opcodeが0x7cc60018の

stmdane r0 {r2,r3,r4,r5,r6,r9,r10,lr,pc}

という命令でした。(この命令はr0をベースアドレスにr2,r3...をまとめてメモリに書き込むという命令と捉えています。)

ですが、ldr命令を実行したところ、上記のopcodeがr4に入るかなと思っていたのですが、実際には0x1800c67cという予想とは異なる値が格納されていました。
その後のコードからどうやら、r4に入っていたそれはアドレスのようですが、ではアドレスが入るなら0x2002c128がそのまま入るべきではないかとも考えました。

考え方で正しくないところがあると思うのでご指摘いただきたいです。
よろしくお願いいたします。

補足情報

ldrの次の行に

bx r4

という分岐命令があるので、これはr4はアドレスという扱いで間違いないでしょうか。
r4にはデータが読み込まれるというイメージだったので、少し混乱しています。
stmdaneがアドレスを生成しているのでしょうか...

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

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

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

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

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

guest

回答2

0

単にエンディアンの問題で無いでしょうか?

「r1に入ってるアドレスに36を足されたアドレスにある命令orデータがr4に入れられる。」

「命令orデータ」ではなく、「データ」ですね。
該当のアドレスに 0x7cc60018が入っていたとのことですが、バイト単位で入れ替える(逆順にする)と、0x1800c67c になりませんか?

[追記]
bx r4 「4.8.1. B、BL、BX、BLX、BXJ」を見ると、分岐と命令セット切り替えですね。
bit0が 0なので、ARM状態で、r4で示されるアドレスに分岐(Branch)するようですね。r4に格納されるのは、データかアドレスか? これはアセンブラの世界(少なくとも ARM)では区別されません。使われる命令によって解釈されるだけです。 BX命令では、アドレスと解釈されるということです。

投稿2019/01/24 11:32

編集2019/01/24 12:43
pepperleaf

総合スコア6383

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

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

marny

2019/01/24 12:05

回答ありがとうございます! またレジスタに入るのはデータだけとのご指摘ありがとうございます。 ちらっと読んだエンディアンのことを忘れていました。。 よければ補足情報にも目を通していただけると幸いです。 よろしくお願いします。
pepperleaf

2019/01/24 12:46

追記しておきました。 マニュアルを見る限り、ARMはリトルエンディアンが基本みたいですね。 ただ、データを読み込むとき、エンディアン変更ができるようです。 (ただし、切り替えは要注意。要仕様確認です)
dodox86

2019/01/24 12:58 編集

補足への回答がかぶりました。失礼しました。
marny

2019/01/24 13:19

>>r4に格納されるのは、データかアドレスか? これはアセンブラの世界(少なくとも ARM)では区別されません。 >>使われる命令によって解釈されるだけです。 BX命令では、アドレスと解釈されるということです。 わからないと唸っていたので、そういうもんなんだと少し気持ちが軽くなりました。 エンディアンについても復習します。ありがとうございました!
guest

0

ベストアンサー

バイトオーダー/エンディアンを意識してみてください。

0x1800c67cを1バイト単位で分解すると0x18, 0x00, 0xc6, 0x7c になりますが、これを逆から再構成すると0x7cc60018 です。

メモリに格納された状態で、下位アドレスから見て0x7c, 0xc6, 0x00, 0x18 になっているものをレジスターにロードすると0x7cc60018になるのがビッグエンディアン(Big Endian)で、0x1800c67cになるのがリトルエンディアン(Little Endian)です。

ARM系CPUは設定次第でどちらにもなれるはずです。


補足情報(?)を受けて追記:2019-01-24 21:54

bx r4 という分岐命令があるので、これはr4はアドレスという扱いで間違いないでしょうか。

ARMのWEBサイトにリファレンスがあるので、そちらを見ましょう。
ARM 命令と Thumb 命令 > BX

「Rm 分岐先アドレスを保持するレジスタを指定します。」と説明されているので、r4レジスターの内容をアドレスとして分岐します。

ただ、ここでBX命令の面白い(注意しなければならない)ところは、命令セットの切り替えも同時に行える、というところです。Rm(ここではR4)レジスターのビット0の値によって、分岐後にARM命令かまたはThumb(サム)命令で動き始めるそうです。Thumb命令とは簡単に言うとフルスペックのARM命令ではなく、命令長や機能を削減して、組み込み用途のような制限のある状況で動くに適したARM系CPUの命令セットのことです。昔のARM CPUにはありませんでしたが、組み込み用途の軽量ARM(Cortex-M系)CPUの出現で出てきたような気がします。

投稿2019/01/24 11:31

編集2019/01/24 12:54
dodox86

総合スコア9183

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

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

marny

2019/01/24 12:08

詳しい回答ありがとうございます! リトルエンディアンとビッグエンディアンのこと、背景含めておさらいしておきます。 よければ補足情報の質問にも目を通していただけると幸いです。 よろしくお願いします。
dodox86

2019/01/24 12:55

追記しましたのでご覧ください。
marny

2019/01/24 13:24

Thumb命令についてわかりやすく解説してくださりありがとうございます。自分でもよく調べてみます。 今触っているのがCortex-Aで性能は一番高いというイメージですがそれでも出てくるのですね、勉強になります。 ありがとうございました!
dodox86

2019/01/24 13:30

Cortex-Aでも省電力や少ないリソースで動かしたい場面とか、動作の選択肢が増える(=多機能)ためでしょうね。
pepperleaf

2019/01/24 13:37

余談ですが、Big/Littleの切り替えは要注意です。 大半は、バイトオーダーですが、ハーフワード(16bit)で入れ替えるCPUも存在します。(昔、引っかかった。関係者が皆、バイトオーダーと思っていた) それ以来、単純に信用しない事にしています。
marny

2019/01/25 04:33

貴重な体験談ありがとうございます. エンディアン切り替えというのはなかなかくせ者なのですね..
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問