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}")