卒論からコピペなどw

この疑問は一度置いておくこととして, こんどは返り値について考えてみよう.
ついでに 1 つの未知の命令の働きを推測する方法も紹介する.
1 int ymzwrite1 ( int value , int adr ){
2 FIO4PIN =0 x00 ;
3 FIO4PIN = adr ;
4 FIO4PIN =(0 x200 + adr );
5 FIO4PIN =(0 x100 + value );
6 FIO4PIN =(0 x300 + value );
7 return adr *16+ value ;
8 }
1     ymzwrite1 :
2    . LFB15 :
3    . loc 1 378 0
4    . cfi_startproc
5    push { r4 , lr }
6    . LCFI19 :
7    . cfi_def_cf a_offs et 8
8    . cfi_offset 4 , -8
9    . cfi_offset 14 , -4
10    . LVL117 :
11    . loc 1 379 0
12    ldr r3 , . L171 @ 左 辺 を 準 備
13    mov r4 , #0 @ ま ず F I O 4 P I N の 右 辺 を 準 備
14    . loc 1 381 0
15    mov r2 , #128 @ 代 入 処 理 を 後 回 し に し て 次 の 仕 込 み
16    @いきなりr2に512を入れないのには , Thumb命令だからという制約があるはず
17    . loc 1 379 0
18    str r4 , [ r3 ] @ r 4 は 0 が 入 っ て い た . 代 入 処 理
19    . loc 1 381 0
20    lsl r4 , r2 , #2 @ r 4 に は 1 2 8 #2 を 代 入
21    add r2 , r1 , r4 @r2 =128#2+ r1 ( adr )
22    . loc 1 382 0
23    add r4 , r0 , #1 @r4 =1+ val
24    . loc 1 380 0
25    str r1 , [ r3 ] @ A d r 代 入
26    . loc 1 382 0
27    add r4 , r4 , #255 @r4 = r4 +255= val +256
28    . loc 1 381 0
29    str r2 , [ r3 ] @ r 2 は 1 2 8 #2+ r1 ( adr ) で あ る . 3 度 目 の 代 入 で あ る
30    @FIO4PIN =(0 x200 + adr ); が 行 わ れ て い る は ず だ .
31    . loc 1 383 0
32    mov r2 , #192 @r2 =192
33    . loc 1 382 0
34    str r4 , [ r3 ] @val +256 を r 3 に 代 入
35    . loc 1 383 0
36    lsl r4 , r2 , #2
37    add r2 , r0 , r4 @r2 = val + r2 (192)#2
38    . loc 1 385 0
39    lsl r1 , r1 , #4 @r1 = r1 #4
40     . LVL118 :
41    add r0 , r1 , r0 @r0 = val + adr #4
42    . LVL119 :
43    . loc 1 383 0
44    str r2 , [ r3 ] @
45    . loc 1 386 0
46    @ sp needed for prologue
47    pop { r4 }
48    pop { r1 }
49    bx r1
以上から,
0x200 + A = 0x80#2 + A
0x300 + B = 0xC0#2 + B
が分かる.
どうやら, 頭の少なくとも 2bit が対応しているという可能性がある. すると, #は
• 加算
• シフト
• 乗算
• その他ビット演算
の可能性がある.
桁数から察するに, 加算はおかしい.
乗算だった場合, 2 が即値であったらありえない.
ここで,
リスト 9.11 戻り値?
1    lsl r1 , r1 , #4 @r1 = r1 #4
2 . LVL118 :
3    add r0 , r1 , r0 @r0 = val + adr #4
に注目する. すると,
adr*16+value;
が [戻り値?] の様に表現されている可能性があるとわかる. さらに戻り値の可能性をおって
いくと, 最初に push した lr を取り出すために, わざと pop {r1} を pop {r4} の後に行って
いることに気づく.
これは戻り先番地である. なぜなら bx r1 があり, どうやら呼び出し元に帰っているという
予測ができるからだ.
するとこの直前に置かれている r0 がもっとも戻り値として最適であるはずだ.
すると, adr×16=adr#4 であることがわかる.
これらの状況は, 明らかに#と lsl がシフト演算である可能性が高い.
その場合, 戻り値は r0 に記述される. この問題は ARM アーキテクチャマニュアルで答え合
わせが出来る. LSL 命令は確かに左シフト演算であった.
Comments are closed, but you can leave a trackback: Trackback URL.