1
0
infernal-interpreter/tests/test_fib.py

80 lines
2.2 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) #infernal.Emulator(fib_iter_prog)
painter = infernal.TikzPainter()
emu.setStack("junk...", "calling eip")
emu.setRegs( rip = 0, rbp = 'old bp', rdi = a )
painter.drawState(emu)
for line_nr in emu:
painter.drawState(emu, line_nr)
painter.drawNames(emu)
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(str(painter))
f.write("\\end{tikzpicture}\n\\end{document}")