アセンブリでHello, world!
ELF Golfなるものが一部で流行っているらしいが,Plan9でやったら8.out Golfになるのかな?
libcを使わずシステムコール呼出しを書いたら,id:yupo5656さんにトラックバックしてもらったので,続きということで,アセンブリで書いてみる.コードは次に示すが,バイナリサイズは94バイトになった(C版は114バイト).SBはstatic baseと呼ばれる疑似レジスタで,プログラムの先頭アドレスを指している.mainや.stringのアドレスはロード時(8l実行時)に決定される.今回はmainが0x1020,.stringがデータセグメントの先頭の0x2000になっていた.ちなみに,システムコールの引数はレジスタを使わず,すべてスタック渡しになる.
TEXT main+0(SB),0,$0 MOVL $1,4(SP) MOVL $.string+0(SB),8(SP) MOVL $14,12(SP) MOVL $20,AX INT $64 MOVL $0,4(SP) MOVL $8,AX INT $64 GLOBL .string+0(SB),$16 DATA .string+0(SB)/8,$"Hello, w" DATA .string+8(SB)/8,$"orld!\z\z\n" END ,
最後のDATA疑似命令の部分は8バイトでアライメントされるのか,次のように書いてもサイズに変化がなかった.
GLOBL .string+0(SB),$14 DATA .string+0(SB)/8,$"Hello, w" DATA .string+8(SB)/6,$"orld!\n"
MOVLよりもPUSHLの方が命令長が短いので,PUSHLを使って書き直すと,77バイトまで縮まった.
TEXT main+0(SB),$0 PUSHL $14 PUSHL $.string+0(SB) PUSHL $1 PUSHL $0 MOVL $20,AX INT $64 PUSHL $0 PUSHL $0 MOVL $8,AX INT $64 GLOBL .string+0(SB),$14 DATA .string+0(SB)/8,$"Hello, w" DATA .string+8(SB)/6,$"orld!\n" END ,
どうせ,exits(2)から戻ることはないので,ちょっとちょんぼして,73バイト.
TEXT main+0(SB),$0 PUSHL $14 PUSHL $.string+0(SB) PUSHL $1 MOVL $20,AX _syscall: PUSHL $0 INT $64 MOVL $8,AX JMP _syscall GLOBL .string+0(SB),$14 DATA .string+0(SB)/8,$"Hello, w" DATA .string+8(SB)/6,$"orld!\n" END ,