1. 7shi

    Posted

    7shi
Changes in title
+SHのPC相対について
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,145 @@
+『[熱血!アセンブラ入門](http://www.amazon.co.jp/dp/4798041807)』の[書籍の補足情報](http://kozos.jp/books/asm/information.html)に以下の記述があります。
+
+> ■ SHのPC相対について (2014/10/04)
+>
+> PC相対によるメモリアクセスの際に,PCの値が4バイトアラインメントされて いるという記述がありますが,すみませんちょっと筆者の勘違いが残ってしまって いたようです.(情けない…)
+>
+> sh-elf.dを実際に見てみたところ,以下のようになっているようです.
+>
+> ・ PC(プログラムカウンタ)は,2つ先の命令を指している.
+> ・ mov.wで2バイトをPC相対でロードする際には,PC+オフセットで アドレスを計算している.(単純に加算するだけ)
+> ・ mov.lで4バイトをPC相対でロードする際には,PCを4バイトアラインメント して,さらにオフセットを加算することでアドレスを計算している. (4バイトロードなので,アラインメントされる)
+
+これについて検証してみました。
+
+# mov.w
+
+`mov.w`命令で近くのメモリから値を読み込みます。
+
+※ 機械語を見るためのコードで、実行は想定していません。
+
+```text:sh1.s
+test0a:
+ mov.w 0f,r0
+ nop
+0: .word 0x7788
+
+test0b:
+ mov.w 0f,r0
+ nop
+0: .word 0x7788
+
+test1a:
+ mov.w 0f,r0
+ nop
+ nop
+0: .word 0x7788
+
+test1b:
+ nop
+ mov.w 0f,r0
+ nop
+ nop
+0: .word 0x7788
+```
+
+`mov.w`命令の相対アドレス(`90 XX`のXXの部分)に注目します。
+
+```text:逆アセンブル結果
+00000000 <test0a>:
+ 0: 90 00 mov.w 4 <test0a+0x4>,r0 ! 7788
+ 2: 00 09 nop
+ 4: 77 88 add #-120,r7
+
+00000006 <test0b>:
+ 6: 90 00 mov.w a <test0b+0x4>,r0 ! 7788
+ 8: 00 09 nop
+ a: 77 88 add #-120,r7
+
+0000000c <test1a>:
+ c: 90 01 mov.w 12 <test1a+0x6>,r0 ! 7788
+ e: 00 09 nop
+ 10: 00 09 nop
+ 12: 77 88 add #-120,r7
+
+00000014 <test1b>:
+ 14: 00 09 nop
+ 16: 90 01 mov.w 1c <test1b+0x8>,r0 ! 7788
+ 18: 00 09 nop
+ 1a: 00 09 nop
+ 1c: 77 88 add #-120,r7
+```
+
+この結果を見ると、4バイトアラインメントの影響はなく、以下の記述は正しいようです。
+
+> ・ PC(プログラムカウンタ)は,2つ先の命令を指している.
+> ・ mov.wで2バイトをPC相対でロードする際には,PC+オフセットで アドレスを計算している.(単純に加算するだけ)
+
+# mov.l
+
+`mov.l`命令で近くのメモリから値を読み込みます。
+
+```text:sh2.s
+test0a:
+ mov.l 0f,r0
+ nop
+0: .long 0x778899aa
+
+test0b:
+ nop
+ mov.l 0f,r0
+0: .long 0x778899aa
+
+test1a:
+ mov.l 0f,r0
+ nop
+ nop
+ nop
+0: .long 0x778899aa
+
+test1b:
+ nop
+ mov.l 0f,r0
+ nop
+ nop
+0: .long 0x778899aa
+```
+
+`mov.l`命令の相対アドレス(`d0 XX`のXXの部分)に注目します。
+
+```text:逆アセンブル結果
+00000000 <test0a>:
+ 0: d0 00 mov.l 4 <test0a+0x4>,r0 ! 778899aa
+ 2: 00 09 nop
+ 4: 77 88 add #-120,r7
+ 6: 99 aa mov.w 15e <test1b+0x142>,r9
+
+00000008 <test0b>:
+ 8: 00 09 nop
+ a: d0 00 mov.l c <test0b+0x4>,r0 ! 778899aa
+ c: 77 88 add #-120,r7
+ e: 99 aa mov.w 166 <test1b+0x14a>,r9
+
+00000010 <test1a>:
+ 10: d0 01 mov.l 18 <test1a+0x8>,r0 ! 778899aa
+ 12: 00 09 nop
+ 14: 00 09 nop
+ 16: 00 09 nop
+ 18: 77 88 add #-120,r7
+ 1a: 99 aa mov.w 172 <test1b+0x156>,r9
+
+0000001c <test1b>:
+ 1c: 00 09 nop
+ 1e: d0 01 mov.l 24 <test1b+0x8>,r0 ! 778899aa
+ 20: 00 09 nop
+ 22: 00 09 nop
+ 24: 77 88 add #-120,r7
+ 26: 99 aa mov.w 17e <test1b+0x162>,r9
+```
+
+この結果を見ると、以下の記述は少し補足が必要なように思います。
+
+> ・ PC(プログラムカウンタ)は,2つ先の命令を指している.
+> ・ mov.lで4バイトをPC相対でロードする際には,PCを4バイトアラインメント して,さらにオフセットを加算することでアドレスを計算している. (4バイトロードなので,アラインメントされる)
+
+一般的にアラインメントでは切り上げすることが多いように思いますが、`a: d0 00`と`1e: d0 01`は切り下げでアラインメントされています。というわけで「切り下げ」を明記した方が誤解が少ないように思います。