79 lines
2.1 KiB
Python
79 lines
2.1 KiB
Python
|
import os,sys,inspect
|
||
|
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
||
|
import infernal
|
||
|
|
||
|
fib_prog = """
|
||
|
fib: push %rbp # push previous base pointer
|
||
|
movq %rsp,%rbp # setup new base pointer
|
||
|
if: cmpq $1, %rdi # if (a-1) > 0: goto long
|
||
|
jg long
|
||
|
quick: movq %rdi, %rax
|
||
|
jmp return
|
||
|
long: pushq %rdi # Push a onto the stack
|
||
|
subq $1, %rdi
|
||
|
call fib # Call fib(a-1)
|
||
|
pushq %rax # Push fib(a-1) onto the stack
|
||
|
subq $1, %rdi
|
||
|
call fib # Call fib(a-2)
|
||
|
popq %rdi # pop fib(a-1) into rdi
|
||
|
addq %rdi, %rax # rax = fib(a-1)+fib(a-2)
|
||
|
popq %rdi # Garentee that a lies in rdi.
|
||
|
return: leave # Clean up (stack pointers?)
|
||
|
ret # return m (rax)
|
||
|
"""
|
||
|
|
||
|
fib_iter_prog = """
|
||
|
fib: push %rbp # push previous base pointer
|
||
|
movq %rsp,%rbp # setup new base pointer
|
||
|
|
||
|
if: cmpq $1, %rdi # if (a-1) > 0: goto loops
|
||
|
jg loops
|
||
|
|
||
|
quick: movq %rdi, %rax
|
||
|
jmp return
|
||
|
|
||
|
loops: movq %rdi, %r8 # i (r8) = a
|
||
|
movq $1, %rdi # minus_one (rdi) = 1
|
||
|
movq $0, %rax # minus_two (rax) = 0
|
||
|
|
||
|
loopb: movq %rdi, %9 # r = minus_one
|
||
|
addq %rax, %rdi # minus_one += minus_two
|
||
|
movq %9, %rax # minus_two = r
|
||
|
subq $1, %r8 # i--
|
||
|
cmpq $0, %r8 # if a > 0
|
||
|
jg loopb
|
||
|
|
||
|
return: leave # Clean up
|
||
|
ret # return m (rax)
|
||
|
"""
|
||
|
|
||
|
|
||
|
OPTIONS = """register_node/.style={rectangle, draw=black!30,
|
||
|
fill=black!5, very thick, minimum size=0.5, minimum width=20mm},
|
||
|
text_node/.style={}"""
|
||
|
|
||
|
def printf (str, *args):
|
||
|
print(str.format(*args))
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
a = 3
|
||
|
printf("Running for fib({})", a)
|
||
|
|
||
|
# Setup
|
||
|
emu = infernal.Emulator(fib_prog)
|
||
|
emu.setStack("junk...","calling eip")
|
||
|
emu.setRegs( rip = 0, rbp = 'old bp', rsp = 1, rdi = a )
|
||
|
|
||
|
emu.drawRegs()
|
||
|
for emu_ in emu:
|
||
|
pass
|
||
|
emu.text += emu.drawNames(0, emu.max_stack_size)
|
||
|
|
||
|
printf("fib({}) = {}", a, emu.registers["%rax"])
|
||
|
|
||
|
with open("tikz.tex","w") as f:
|
||
|
f.write("\\documentclass{standalone}\n\n\usepackage{tikz}\\begin{document}\n")
|
||
|
f.write("\\begin{tikzpicture}["+OPTIONS+"]\n")
|
||
|
f.write(emu.text)
|
||
|
f.write("\\end{tikzpicture}\n\\end{document}")
|