Pro Yearly is on sale from $80 to $50! »

Simulating a CPU with Ruby

Simulating a CPU with Ruby

Be732ee41fd3038aa98a0a7e7b7be081?s=128

Denis Defreyne

April 02, 2015
Tweet

Transcript

  1. Simulating a CPU with Ruby Denis Defreyne / RUG::B /

    April 2, 2015 1
  2. May contain nuts. 2 DISCLAIMER

  3. 3 1. Write an assembler 2. Design an assembly language

    3. Design a CPU instruction format 4. Design a CPU instruction set 5. Write an emulator
  4. 3 1. Write an assembler 2. Design an assembly language

    3. Design a CPU instruction format 4. Design a CPU instruction set 5. Write an emulator
  5. 3 1. Write an assembler 2. Design an assembly language

    3. Design a CPU instruction format 4. Design a CPU instruction set 5. Write an emulator
  6. 3 1. Write an assembler 2. Design an assembly language

    3. Design a CPU instruction format 4. Design a CPU instruction set 5. Write an emulator
  7. 3 1. Write an assembler 2. Design an assembly language

    3. Design a CPU instruction format 4. Design a CPU instruction set 5. Write an emulator
  8. 3 1. Write an assembler 2. Design an assembly language

    3. Design a CPU instruction format 4. Design a CPU instruction set 5. Write an emulator
  9. 4

  10. 4

  11. 4

  12. 5

  13. loop do 5

  14. loop do grab
 5

  15. loop do grab
 case apple_color 5

  16. loop do grab
 case apple_color when :red 5

  17. loop do grab
 case apple_color when :red move_to(:right) 5

  18. loop do grab
 case apple_color when :red move_to(:right) when :green

    5
  19. loop do grab
 case apple_color when :red move_to(:right) when :green

    move_to(:left) 5
  20. loop do grab
 case apple_color when :red move_to(:right) when :green

    move_to(:left) end
 5
  21. loop do grab
 case apple_color when :red move_to(:right) when :green

    move_to(:left) end
 release 5
  22. loop do grab
 case apple_color when :red move_to(:right) when :green

    move_to(:left) end
 release move_to(:middle) 5
  23. loop do grab
 case apple_color when :red move_to(:right) when :green

    move_to(:left) end
 release move_to(:middle) end 5
  24. A program is a stream of instructions. 6

  25. 7 loop do grab case apple_color when :red move_to(:right) when

    :green move_to(:left) end release move_to(:bucket) end
  26. 7 loop do grab case apple_color when :red move_to(:right) when

    :green move_to(:left) end release move_to(:bucket) end
  27. grab # grab apple 7 loop do grab case apple_color

    when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  28. grab # grab apple getcolor r0 # r0 now contains

    apple color 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  29. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  30. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  31. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  32. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  33. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  34. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  35. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  36. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  37. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  38. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 done: 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  39. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 done: release # release apple (falls in target pile) 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  40. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 done: release # release apple (falls in target pile) mvarm 0 # move arm (0 means middle) 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  41. grab # grab apple getcolor r0 # r0 now contains

    apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 done: release # release apple (falls in target pile) mvarm 0 # move arm (0 means middle) jmp @start # jump 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  42. start: grab # grab apple getcolor r0 # r0 now

    contains apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 done: release # release apple (falls in target pile) mvarm 0 # move arm (0 means middle) jmp @start # jump 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  43. start: grab # grab apple getcolor r0 # r0 now

    contains apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 done: release # release apple (falls in target pile) mvarm 0 # move arm (0 means middle) jmp @start # jump 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  44. start: grab # grab apple getcolor r0 # r0 now

    contains apple color cmp r0, 0 # 0 means red je @red # jump if equal (i.e. red) jmp @green # jump
 green: mvarm 1 # move arm (1 means left) jmp @done # jump
 red: mvarm 2 # move arm (2 means right) jmp @done # jump
 done: release # release apple (falls in target pile) mvarm 0 # move arm (0 means middle) jmp @start # jump 7 loop do grab case apple_color when :red move_to(:right) when :green move_to(:left) end release move_to(:bucket) end
  45. 8

  46. lv r0, 123 8

  47. lv r0, 123 prn r0 8

  48. lv r0, 123 prn r0 halt 8

  49. prn is not a realistic instruction. 9 CHEAT #1

  50. CHEAT #1 halt is not a realistic instruction. 10 CHEAT

    #2
  51. 11

  52. lv r0, 100 11

  53. lv r0, 100 lv r1, 200 11

  54. lv r0, 100 lv r1, 200 add r2, r0, r1

    11
  55. lv r0, 100 lv r1, 200 add r2, r0, r1

    prn r2 11
  56. lv r0, 100 lv r1, 200 add r2, r0, r1

    prn r2 halt 11
  57. def gcd(a, b) while b != 0 t = b

    b = a % b a = t end a end 12
  58. 13 def gcd(r0, r1) while r1 != 0 r2 =

    r1 r1 = r0 % r1 r0 = r2 end r0 end
  59. lv r0, 819000 # r0 = 819000 13 def gcd(r0,

    r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  60. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  61. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  62. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  63. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  64. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 mod r1, r0, r1 # r1 <— r0 % r1 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  65. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 mod r1, r0, r1 # r1 <— r0 % r1 mov r0, r2 # r0 <— r2 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  66. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 mod r1, r0, r1 # r1 <— r0 % r1 mov r0, r2 # r0 <— r2 jmp @start # jump to @start
 
 
 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  67. lv r0, 819000 # r0 = 819000 lv r1, 254163

    # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 mod r1, r0, r1 # r1 <— r0 % r1 mov r0, r2 # r0 <— r2 jmp @start # jump to @start
 
 
 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end 
 
 
 start: 
 
 
 
 
 
 
 

  68. 
 
 
 
 
 
 
 
 
 


    
 end: lv r0, 819000 # r0 = 819000 lv r1, 254163 # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 mod r1, r0, r1 # r1 <— r0 % r1 mov r0, r2 # r0 <— r2 jmp @start # jump to @start
 
 
 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end 
 
 
 start: 
 
 
 
 
 
 
 

  69. 
 
 
 
 
 
 
 
 
 


    
 end: prn r0 # print r0 (our gcd!) lv r0, 819000 # r0 = 819000 lv r1, 254163 # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 mod r1, r0, r1 # r1 <— r0 % r1 mov r0, r2 # r0 <— r2 jmp @start # jump to @start
 
 
 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end 
 
 
 start: 
 
 
 
 
 
 
 

  70. 
 
 
 
 
 
 
 
 
 


    
 end: prn r0 # print r0 (our gcd!) halt # shut down lv r0, 819000 # r0 = 819000 lv r1, 254163 # r1 = 254163
 
 cmp r1, 0 # compare r1 with 0 je @end # jump to @end if = mov r2, r1 # r2 <— r1 mod r1, r0, r1 # r1 <— r0 % r1 mov r0, r2 # r0 <— r2 jmp @start # jump to @start
 
 
 13 def gcd(r0, r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end 
 
 
 start: 
 
 
 
 
 
 
 

  71. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 0113 0100 010f 0002 060c 0e00 ff 14
  72. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 15
  73. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 15
  74. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 15
  75. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 15
  76. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 0720 je @end 15
  77. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 0720 je @end 0f02 01 mov r2, r1 15
  78. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 0720 je @end 0f02 01 mov r2, r1 1301 0001 mod r1, r0, r1 15
  79. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 0720 je @end 0f02 01 mov r2, r1 1301 0001 mod r1, r0, r1 0f00 02 mov r0, r2 15
  80. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 0720 je @end 0f02 01 mov r2, r1 1301 0001 mod r1, r0, r1 0f00 02 mov r0, r2 060c jmp @start 15
  81. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 0720 je @end 0f02 01 mov r2, r1 1301 0001 mod r1, r0, r1 0f00 02 mov r0, r2 060c jmp @start 0e00 prn r0 15
  82. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 1000 000c 7f38 lv r0, 819000 1001 0003 e0d3 lv r1, 254163 1201 0000 0000 cmp r1, 0 0720 je @end 0f02 01 mov r2, r1 1301 0001 mod r1, r0, r1 0f00 02 mov r0, r2 060c jmp @start 0e00 prn r0 ff halt 15
  83. Machine code is executed by actual, physical CPUs. Bytecode is

    executed by virtual machines. 16
  84. 17 YARV

  85. 18 JVM

  86. 0000000000001f76 <_rb_ary_freeze>: 1f76: 55 push %rbp 1f77: 48 89 e5

    mov %rsp,%rbp 1f7a: 5d pop %rbp 1f7b: e9 32 b6 07 00 jmpq 7d5b2 <_rb_obj_freeze> 0000000000002483 <_rb_ary_free>: 2483: 55 push %rbp 2484: 48 89 e5 mov %rsp,%rbp 2487: 40 f6 c7 07 test $0x7,%dil 248b: 75 23 jne 24b0 <_rb_ary_free+0x2d> 248d: 48 89 f8 mov %rdi,%rax 2490: 48 83 e0 f7 and $0xfffffffffffffff7,%rax 2494: 74 1a je 24b0 <_rb_ary_free+0x2d> 2496: 48 8b 07 mov (%rdi),%rax 2499: 48 89 c1 mov %rax,%rcx 249c: 48 83 e1 1f and $0x1f,%rcx 24a0: 48 83 f9 1c cmp $0x1c,%rcx 24a4: 74 0a je 24b0 <_rb_ary_free+0x2d> 24a6: 48 25 00 60 00 00 and $0x6000,%rax 24ac: 74 02 je 24b0 <_rb_ary_free+0x2d> 24ae: 5d pop %rbp 24af: c3 retq 24b0: 48 8b 7f 20 mov 0x20(%rdi),%rdi 24b4: 5d pop %rbp 24b5: e9 23 39 04 00 jmpq 45ddd <_ruby_xfree> 19 X86
  87. 0010c00 <main.init.1>: 10c00: e59a1008 ldr r1, [sl, #8] 10c04: e15d0001

    cmp sp, r1 10c08: 91a0300e movls r3, lr 10c0c: 9b01a46b blls 79dc0 <runtime.morestack_noctxt> 10c10: 9afffffa bls 10c00 <main.init.1> 10c14: e52de044 str lr, [sp, #-68]! ; 0xffffffbc 10c18: e59fb19c ldr fp, [pc, #412] ; 10dbc <main.init.1+0x1bc> 10c1c: e5db0000 ldrb r0, [fp] 10c20: e3500000 cmp r0, #0 10c24: 0a000062 beq 10db4 <main.init.1+0x1b4> 10c28: e59f1190 ldr r1, [pc, #400] ; 10dc0 <main.init.1+0x1c0> 10c2c: e28d0004 add r0, sp, #4 10c30: e4912004 ldr r2, [r1], #4 10c34: e4802004 str r2, [r0], #4 10c38: e4912004 ldr r2, [r1], #4 10c3c: e4802004 str r2, [r0], #4 10c40: eb021a3a bl 97530 <os.Getenv> 10c44: e28d000c add r0, sp, #12 10c48: e5901000 ldr r1, [r0] 10c4c: e5901004 ldr r1, [r0, #4] 10c50: e58d1034 str r1, [sp, #52] ; 0x34 10c54: e59d0034 ldr r0, [sp, #52] ; 0x34 10c58: e3500000 cmp r0, #0 10c5c: 0a000054 beq 10db4 <main.init.1+0x1b4> 10c60: e59f115c ldr r1, [pc, #348] ; 10dc4 <main.init.1+0x1c4> 10c64: e28d0004 add r0, sp, #4 10c68: e4912004 ldr r2, [r1], #4 10c6c: e4802004 str r2, [r0], #4 10c70: e4912004 ldr r2, [r1], #4 10c74: e4802004 str r2, [r0], #4 20 ARM
  88. 21 THE SECRET OF MONKEY ISLAND

  89. 22

  90. 22 1. Fetch instruction

  91. 22 1. Fetch instruction 2. Execute instruction

  92. 22 1. Fetch instruction 2. Execute instruction 3. Move to

    next instruction
  93. 23 RPC Program counter

  94. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 24 RPC 0
  95. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 24 RPC 6
  96. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 24 RPC 12
  97. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 24 RPC 18
  98. 1000 000c 7f38 1001 0003 e0d3 1201 0000 0000 0720

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 24 RPC 20
  99. 25 General-purpose registers R0 - R7

  100. 26 RFLAGS Flags register (equal, greater than)

  101. 27 j je jne jg jge jl jle cmp mod

    add sub mul div xor or and shl shr not lw lh lb sw sh sb STACK FUNC SPECIAL call ret push pop prn halt BRANCHING ARITHMETIC mov li MEMORY REG
  102. DEMO 28

  103. github.com/ddfreyne/rcpu 29

  104. 30 @ddfreyne denis@stoneship.org Denis Defreyne Ask me about Belgian beer.

  105. 31 This talk would not have been the same without

    some great assets that I could use for free. The fonts in this presentation are Clear Sans by Intel (01.org/clear-sans) and Ubuntu Mono by Canonical Ltd (font.ubuntu.com). The apple sprite is by http://chrisdesign.wordpress.com/.
  106. Extra slides 32

  107. 33

  108. 33 25 15

  109. 33 25 15 RPC + 5

  110. 33 25 15 RPC + 5 CALLER

  111. 33 25 15 RPC + 5 CALLER CALLEE

  112. 33 25 15 RPC + 5 old RBP CALLER CALLEE

  113. 33 25 15 RPC + 5 old RBP old R0

    old R1 old R2 CALLER CALLEE
  114. 33 25 15 RPC + 5 old RBP CALLER CALLEE

  115. 33 25 15 RPC + 5 CALLER CALLEE

  116. 33 25 15 CALLER CALLEE

  117. 33 CALLER CALLEE

  118. 34

  119. lv r0, 100 34

  120. lv r0, 100 cmpi r0, 100 # rflags is now

    0x01 (equal) 34
  121. lv r0, 100 cmpi r0, 100 # rflags is now

    0x01 (equal) cmpi r0, 99 # rflags is now 0x02 (greater than) 34
  122. 35 RIVEN

  123. 36 RIVEN

  124. 37 Z-CODE

  125. 38 MARGARET HAMILTON