Pythonアセンブラw

今日はPythonの中でアセンブリを書こうと思います。
まだ初歩的なものしか書けないので Hello worldを出力させようと思います。

#test_write.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pyasm import Program
from pyasm.data import String
from pyasm.registers import eax,ebx,ebp,ecx,edx
from pyasm.macro import syscall
from pyasm.instructions import mov,ret,push,add

def example():
	msg = "Hello, World\n"
	prog = Program(
		mov(ebx,1),
		mov(ecx,String(msg)),
		mov(edx,len(msg)),
		syscall('write'),
		ret(),
	)
	fun = prog.compile()
	fun()
if __name__ == '__main__':
	example()

簡単に説明します。

#Programがソースを書くための土台です。
from pyasm import Program
#後ほど説明します。
from pyasm.data import String
#レジスタを設定します。どのレジスタを使うか決めます。
from pyasm.registers import eax,ebx,ebp,ecx,edx
#システムコールを呼べるようにしてるんかなぁ…w
from pyasm.macro import syscall
#命令です
from pyasm.instructions import mov,ret,push,add

#example関数
def example():
    #msgに代入
	msg = "Hello, World\n"
	prog = Program(
		mov(ebx,1),
		mov(ecx,String(msg)),
		mov(edx,len(msg)),
		syscall('write'),
		ret(),
	)

ん〜、ちょっと分からんのが、
順番なんですよねぇ〜。
アセンブリなら

movl $4,%eax #writeのシステムコール
movl $1,%ebx  #1stdout
movl $msg,%ecx  #msgは文字列のポインタ
movl $msg_len,%edx  #msg_lenmsgの文字数
int  $0x80

でかけるんですが、 Pythonはどうやらちょっと違うっぽいです。

syscall('write')なら直接っぽいですね。

ちなみに、
%ecxに入ってるのは 文字列のポインタなので

>>> from pyasm.data import String
>>> a = "Hello world"
>>> b = String(a)
>>> b
<pyasm.data.String object at 0xb736ba8c>
>>> 

って感じです。
Stringは文字列のアドレスを表記するものですねぇ。
それを %ecx に代入してるって分かればまぁ納得出来ますね。

 #アセンブリで書いたので compileしないとダメそうですね。
    fun = prog.compile()
   #返り値は fun() ですかね。
    fun() 

一通り説明は終わりましたぁ〜

結果は

ashigirl96@bt:~$ python test_write.py 
Hello, World
ashigirl96@bt:~$