ラズパイでアセンブラ書いてみた


JAVAやPython、JavaScriptやGAS(最近個人的に好きな言語)など、さまざまなプログラミング言語は高級言語と呼ばれ、広く普及しています。
僕みたいな貧乏は「高級」と聞くだけで、恐れ多くなってしまい自然と「低級」なものを求めてしまいます。

ということで今日は、低級言語であるアセンブラにザックリと触れていこうと思います。
いつものごとく、RaspberryPiを用います。(半導体不足の影響なのか、新しいラスパイ全然手に入らないんだが)

言語プロセッサ

まず最初にアセンブラという言葉にあまり聞き馴染みのない方向けに簡単に解説をします。
コンピュータは原理的にバイナリーしか理解できないでの、人間とコンピュータの間には言語を翻訳してくれる存在が必要です。
その翻訳家のことを言語プロセッサと呼びます。
言語プロセッサには、大きく分けて「コンパイラ」「インタプリタ」「アセンブラ」があり、それぞれ特徴はありますが今回はアセンブラに限って説明をします。

アセンブラ

アセンブラ(assembler)とは、アセンブリ言語で書かれたソースコードを機械語に変換する言語プロセッサのことです。アセンブラを使いアセンブリ言語を機械語へ変換することをアセンブルといいます。
機械語はバイナリーで記載されており、バイナリーのコードとほぼ一対一の関係で記載するのがアセンブリ言語です。
アセンブリ言語は、コンパイラやインタプリタを用いる他のプログラミング言語よりも低水準な位置付けとなっていますので、初見で読み切るのは困難です。

さらに言うと、アセンブリ言語の命令文は使用するCPUのアーキテクチャなどで異なるため、使用するコンピュータによって完成するコードは異なります。
これはレジスタの配置や使用できるメモリ領域が異なるために発生します。

ちょっと触ってみる

今回は色々な記事なども参考にさせていただきながら、ラズパイのアセンブラを勉強してみました。
アセンブラはPIC/AVRマイコンで触れていた程度なので、ARMコアのアセンブラは初めてです。

ARMの命令セットについては以下を参照↓

今回は、「Hello World!」を出力するだけのコードを書いてみました。
C言語であればほんの数行で終わる内容ですが、泥臭いアセンブラはそうはいきません。

test.s
.data
hello:
	.asciz "Hello World!\n" @.ascizは番兵(null)つきの文字列と勝手に解釈している

.text 
	.align 4
	.global main 

main:
	mov r4, lr 
	ldr r0, =hello
	bl printf 

	mov r0, #0 
	mov lr, r4 

	bx lr @return

それぞれの命令の細かい説明をしようと思っていましたが、それはまた次回以降・・・(書くとは言っていない)
movやらldrなど、ARM以外のアーキテクチャでも使用されているような命令セットが使えるので、PICやらでアセンブラを書いていた人からすれば比較的シンプルに見えるかもしれません。
ちなみに@から後ろはコメントアウトです。

上記のコードを書いたら、実行していきます。
gccでオブジェクトファイルにしてから実行します。

実行
# gcc -g test.s -o test
# ./test

上記のコマンドを打ってみるとしっかりとHello Worldが実行されていることがわかりますね。

※Kaliでroot取るとドクロが表示される仕様なだけで、イキっているわけではないです

正直よくわかっていないこと

色々調べた結果、printする方法として「bl printf」としていますが、これはGNUコンパイラが持っているprintf関数をcallしているという認識でいいのでしょうかね??

objdumpして中身を見て結果「bl 0 <printf>」となっているので、そんな気がしていたのですが・・・まだまだ勉強が足りていないです。
ただ、今後はもう少し知識の汎用性がありそうなx86のアセンブラを勉強していこうと思っています。

実行
┌──(root💀kali-rpi)
└─# objdump test.o -S

test.o:     file format elf32-littlearm

Disassembly of section .text:

00000000 <main>:
   0:	e1a0400e 	mov	r4, lr
   4:	e59f000c 	ldr	r0, [pc, #12]	; 18 <main+0x18>
   8:	ebfffffe 	bl	0 <printf>
   c:	e3a00000 	mov	r0, #0
  10:	e1a0e004 	mov	lr, r4
  14:	e12fff1e 	bx	lr
  18:	00000000 	.word	0x00000000

参考にしたサイト

公式ドキュメント

アセンブラに触れてみよう

※下記記事で触れているのはARMではなくX86系です