BakingPi (4)

ちょい前にも確認したのですが、asm から手続き呼び出しな ABI (Application Binary Interface) なナニ。曰く r0 および r1 については以下な記述。

r0 and r1 are used for passing the first two arguments to functions, and returning the results of functions. if a function does not use them for a return value, they can take any value after a function.

Lesson 3 OK 03 より引用
あるいは r2、r3 が以下。

r2 and r3 are used for passing the second two arguments to functions. There values after a function called can be anything.

Lesson 3 OK 03 より引用
あと戻り番地は Link Register で云々、とありますね。

最初は

GPIO なアドレスの getter を作る模様。以下を gpio.s として云々、とのこと。

.globl GetGpioAddress
GetGpioAddress:
ldr r0,=0x20200000
mov pc,lr

最初の行で global なシンボルとしてのラベルが定義 (宣言?) されて、r0 に GPIO な base address を格納しといて lr に退避されてる戻り番地を pc に mov してます。
手続き定義の基本が列挙されてるカンジですね。

  • 手続きをグローバルなシンボルとして認識頂く方法
  • 戻り値の設定方法
  • 戻る方法

が分かりました。

次はもう少し大きい模様

GPIO の 16 な pin を enable にする手続きを定義する模様。引数として

  • r0 は GPIO Function Select な pin 番号な 0 から 53 の数値
  • r1 は pin にアサインされた手続きを判別する 0 から 7 の数値

が渡される形になっててより抽象化されてます。ということで最初のあたりで引数の値の範囲のチェックをして異常があればそのまま戻る形になってます。

.globl SetGpioFunction
SetGpioFunction:
cmp r0,#53
cmpls r1,#7
movhi pc,lr

movhi はどっちかの cmp が、ではなくて cmp で r0 が 53 より大きければ cmpls は実行されない、とありますね。接尾辞云々についてはまた別途、みたいなことが書いてあるな。ちょっとよく分かりませんがここではスルーということで。
次は以下とのこと。

push {lr}
mov r2,r0
bl GetGpioAddress

GetGpioAddress を呼び出すので lr を push してます。あと r0 を退避してますね。これは GetGpioAddres が値を戻すのに使うのが分かってるからなのか。普通は r4 とか r5 とかを使いなさい、と書いてありますね。あとは bl という命令が手続きの呼び出しで lr に次の命令のアドレスが格納される、と補足されてます。
あと、push の記述なんですがリストの形で書くことができるみたい。これはなかなかアレ。
というか次に出てくる以下な一連の命令が直観的に理解できなかったのですが

functionLoop$:
    cmp r2,#9
    subhi r2,#10
    addhi r0,#4
    bhi functionLoop$

これ、subhi とか addhi とか bhi というのがフラグレジスタの値 (というか cmp の結果) によって実行されるかどうかがアレなのか。
ちなみにこれ、GPIO function select 0 なら FSEL0 から FSEL9 でアドレスは 0x7E200000 で次の GPIO function select 1 なら FSEL10 から FSEL19 でアドレが 0x7E200004 てあたりが根拠になってるんですね。
で最後に以下とのこと。

add r2, r2,lsl #1
lsl r1,r2
str r1,[r0]
pop {pc}

ここ、r1 には 0 から 7 までの数値が格納されてますが、これを function select 向けに適切な位置にシフトで持っていってあげる必要があるのか。
右に記載されてる補足によれば

  • add reg, #val は reg の値に #val を加算して格納、か
  • reg, lsl #val は命令実行前に左 shift なのか
    • これ r2 な番号掛ける 3 か成程

ぐぬぬ。理屈が全部理解できてないと手続きの記述がさくっとアタマに入ってこないですね。

SetGpio

こちら別途で確認の方向で。つうか色々忘れ気味なので整理した方が良さげ。

とりあえず

/*
* Set GPIO 16 to low, causing the LED to turn on.
*/
str r1,[r0,#40]

というあたりを抽象化すべく、というあたりは理解できてるはず。