非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

アセンブラ(18)

乗除算が実行できるようになりました。

実行例(乗算)

int mul(int x, int y) {
	return x * y;
}

これをコンパイルすると以下のようなアセンブリ言語のコードが得られます。

_Z3mulii:
	move.l 8(%sp),-(%sp)
	move.l 8(%sp),-(%sp)
	jsr __mulsi3
	addq.l #8,%sp
	rts

これは __mulsi3 のサブルーチンがないのでこのままでは実行できません。以下のような疑似関数を使えるようにします。

「*call_lmuls」は「jsr __mulsi3」の代わりに使えるものです。これを使うと以下のようになります。

_Z3mulii:
	move.l 8(%sp),-(%sp)
	move.l 8(%sp),-(%sp)
	*call_lmuls
	addq.l #8,%sp
	rts

「*lmuls」はサブルーチンの本体の代わりに使えるものです。これを使うと以下のようになります。

_Z3mulii:
	move.l 8(%sp),-(%sp)
	move.l 8(%sp),-(%sp)
	jsr __mulsi3
	addq.l #8,%sp
	rts
__mulsi3:
	*lmuls
	rts

実行例(除算)

int divi(int x, int y) {
	return x / y;
}

これをコンパイルすると以下のようなアセンブリ言語のコードが得られます。

_Z4diviii:
	move.l 8(%sp),-(%sp)
	move.l 8(%sp),-(%sp)
	jsr __divsi3
	addq.l #8,%sp
	rts

これは __divsi3 のサブルーチンがないのでこのままでは実行できません。以下のような疑似関数を使えるようにします。

「*call_ldivs」は「jsr __divsi3」の代わりに使えるものです。これを使うと以下のようになります。

_Z4diviii:
	move.l 8(%sp),-(%sp)
	move.l 8(%sp),-(%sp)
	*call_ldivs
	addq.l #8,%sp
	rts

「*ldivs」はサブルーチンの本体の代わりに使えるものです。これを使うと以下のようになります。

_Z4diviii:
	move.l 8(%sp),-(%sp)
	move.l 8(%sp),-(%sp)
	jsr __divsi3
	addq.l #8,%sp
	rts
	rts
__divsi3:
	*ldivs
	rts

疑似関数

  • *lmulu, *lmuls, *call_lmulu, *call_lmuls
    • 乗算の関数の代わりに使う
    • 「u」が付くものは符号なし、「s」が付くものは符号あり
    • 「call_」が付くものは関数呼び出しの代わりに使う
  • *ldivu, *ldivs, *call_ldivu, *call_ldivs
    • 除算の関数の代わりに使う
    • 「u」が付くものは符号なし、「s」が付くものは符号あり
    • 「call_」が付くものは関数呼び出しの代わりに使う
  • *dsin, *call_dsin
    • sin 関数の代わりに使う
    • 「call_」が付くものは関数呼び出しの代わりに使う
  • *dcos, *call_dcos
    • cos 関数の代わりに使う
    • 「call_」が付くものは関数呼び出しの代わりに使う
  • *dsqrt, *call_dsqrt
    • sqrt 関数の代わりに使う
    • 「call_」が付くものは関数呼び出しの代わりに使う
  • *itod, *call_itod
    • 整数から浮動小数点数への変換関数の代わりに使う
    • 「call_」が付くものは関数呼び出しの代わりに使う