Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Simulating a CPU with Ruby

Simulating a CPU with Ruby

Denis Defreyne

April 02, 2015
Tweet

More Decks by Denis Defreyne

Other Decks in Technology

Transcript

  1. 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
  2. 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
  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. 4

  8. 4

  9. 4

  10. 5

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

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

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

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

    :green move_to(:left) end release move_to(:bucket) end
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 8

  34. 11

  35. def gcd(a, b) while b != 0 t = b

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

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

    r1) while r1 != 0 r2 = r1 r1 = r0 % r1 r0 = r2 end r0 end
  38. 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
  39. 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
  40. 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
  41. 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
  42. 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
  43. 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
  44. 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
  45. 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: 
 
 
 
 
 
 
 

  46. 
 
 
 
 
 
 
 
 
 


    
 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: 
 
 
 
 
 
 
 

  47. 
 
 
 
 
 
 
 
 
 


    
 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: 
 
 
 
 
 
 
 

  48. 
 
 
 
 
 
 
 
 
 


    
 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: 
 
 
 
 
 
 
 

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

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

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 15
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 22

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

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

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

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

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

    0f02 01 1301 0001 0f00 02 060c 0e00 ff 24 RPC 20
  69. 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
  70. 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/.
  71. 33

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

    old R1 old R2 CALLER CALLEE
  73. 34

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

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