【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

gcc

Lions' Commentary on UNIX 読書会 Part 002に参加しました。初回は参加できなかったため途中参加となりましたが、いきなりアドレスが8進数で書かれているのに面食らいました。アドレスは16進数に変換してどうにか理解できましたが、アセンブリ言語がよく分かりません。そこでPDP-11用のgccを用意して、出力されたアセンブリを眺めながら慣れてみることにしました。

binutilsgccPDP-11に対応済みなので、特にパッチなどを当てなくても、--target=pdp11-aoutですんなりビルドできました。

テスト

どんなコードが生成されるのかテストします。

add.c
int add(int a, int b) { return a + b; }

コンパイルしてアセンブリを出力します。

% pdp11-aout-gcc -S add.c
add.s
	.text

	.even
	.globl _add
_add:

	;	/* function prologue add*/
	mov r5, -(sp)
	mov sp, r5
	;/* end of prologue */

	mov 04(r5), r0
	add 06(r5), r0

	;	/*function epilogue */
	mov r5, sp
	mov (sp)+, r5
	rts pc
	;/* end of epilogue*/

プロローグやエピローグが明示されていて、親切な出力です。movのオペランドAT&T形式と同じで1→2です。movでspを動かしているのは、push/popに相当します。理解の補助として擬似コードx86で表現してみます。

PDP-11 擬似コード x86(nasm)
mov r5, -(sp) *(--sp) = r5 push bp
mov sp, r5 r5 = sp mov bp, sp
mov 04(r5), r0 r0 = *(r5 + 4) mov ax, [bp+4]
add 06(r5), r0 r0 += *(r5 + 6) add ax, [bp+6]
mov r5, sp sp = r5 mov sp, bp
mov (sp)+, r5 r5 = *(sp++) pop bp
rts pc return ret

オブジェクトファイルを逆アセンブルして、どんなバイナリが出力されているか確認します。

% pdp11-aout-gcc -c add.c
% pdp11-aout-objdump -d add.o

add.o:     file format a.out-pdp11


Disassembly of section .text:

00000000 <_add>:
   0:   1166            mov     r5, -(sp)
   2:   1185            mov     sp, r5
   4:   1d40 0004       mov     4(r5), r0
   8:   6d40 0006       add     6(r5), r0
   c:   1146            mov     r5, sp
   e:   1585            mov     (sp)+, r5
  10:   0087            rts     pc

この例では、命令・オペランド共にワード単位のようです。

こんな感じで簡単なものから試しながら、PDP-11のアセンブリ言語に慣れていこうと思います。