Explaining the code: dup

Now let’s look at the piece of code that implements DUP which takes the value on top of the stack and doubles it:

              ┌───┐
         DUP  │ 3 │
  ┌───┐       ├───┤
  │ 3 │       │ 3 │
──┴───┴───────┴───┴──
            0x27: 0x0028   
    PC ---> 0x28: 0xB461    POP A, DB[SP]   
            0x29: 0x8614    PUSH DB[SP], A  
            0x2A: 0x8614    PUSH DB[SP], A
            0x2B: 0x2043    LD A, *(IP)  (instructions for NEXT)
             …       …      

            0x39: 0x0003    
DB[SP] ---> 0x3A: 0xFFFF
            0x3B: 0xFFFF

First we retrieve the value on the top of the stack into a temporary register, here register A. We do that with POP A, DB[SP].

               A: 0x03

            0x27: 0x0028   
            0x28: 0xB461    POP A, DB[SP]   
    PC ---> 0x29: 0x8614    PUSH DB[SP], A  
            0x2A: 0x8614    PUSH DB[SP], A  
            0x2B: 0x2043    LD A, *(IP)  (instructions for NEXT)
             …       …      

DB[SP] ---> 0x39: 0x0003    
            0x3A: 0xFFFF
            0x3B: 0xFFFF

Then we put it back twice by doing PUSH DB[SP], A two times.

               A: 0x03

            0x27: 0x0028   
            0x28: 0xB461    POP A, DB[SP]   
            0x29: 0x8614    PUSH DB[SP], A  
    PC ---> 0x2A: 0x8614    PUSH DB[SP], A  
            0x2B: 0x2043    LD A, *(IP)  (instructions for NEXT)
             …       …      

            0x39: 0x0003    
DB[SP] ---> 0x3A: 0xFFFF
            0x3B: 0xFFFF
               A: 0x03

            0x27: 0x0028   
            0x28: 0xB461    POP A, DB[SP]   
            0x29: 0x8614    PUSH DB[SP], A  
    PC ---> 0x2A: 0x8614    PUSH DB[SP], A  
            0x2B: 0x2043    LD A, *(IP)  (instructions for NEXT)
             …       …      

            0x39: 0x0003    
            0x3A: 0x0003
DB[SP] ---> 0x3B: 0xFFFF

To finish the implementation of DUP, we have to execute the instructions for NEXT as described in a previous post.