This is a hypothetical machine. 
        It is used to illustrate a structure of processor. 
        We can define and program this machine on paper. 
        It has a minimal set of instructions that have simple form. 
        First, we define the machine itself. 
        
Z0 has fixed width instructions. Its natural size is 32
      bits.  It has 16 registers. 
        
    <picture of architecture of Z0>
Z0 has what is called “single address” instruction
      format.  That is, an
      instruction has only one argument. An instruction is 32-bit, with opcode 8
      bits and operand 24 bits.
Opcode:8  
          Operand:24
We define the first group of instruction
      <operator> or <op>
Assembly language:  
        op reg        
        
r0..r15add, sub, inc, decThe result is mostly stored in a special register
      called “accumulator”.  Most
      operators store results there.  
add r1      
          means    ac
        = ac + r1sub r1               
          ac = ac – r1inc r1               
          r1 = r1 + 1dec r1               
          r1 = r1 – 1 Another group of instructions perform data movement
      between registers.
mov r1               
          ac = r1mvi n                
          ac  = n       
        where n is a 24-bit constant, called immediateput r1               
          r1 = ac       
        that is a compliment operation of mov r1The next group of instructions is the logic group. They
      are used for comparison of two values. 
        They affect “flag” in the machine. 
        This flag is one bit storage (True/False) and it is used in the
      transfer of control instruction (explain next).
<logic op>     
        eq  ne 
          lt  le 
          gt  ge 
          z        
        equal, not equal, less that, less than or equal … 
        zero
eq r1                
          flag = (ac == r1)ne r1                
          flag = (ac != r1)lt r1                
          flag = (ac < r1)… z r1                  flag
        = (r1 == 0)The next group of instructions affects the transfer of
      control of program (or jump).  
jmp ads                       
        unconditional jump to ads, where ads is the location of the
      instructionjt ads                         
        jump to ads if flag is Truejf ads                         
        jump to ads if flag is Falsestop                             
        this is a pseudo instruction to tell us that the program has
      ended.Please note that Z0 as defined right now, does not have
      “external” memory (we will add that later). 
        All it has is the internal registers (16 of them). 
        Each can hold a 32-bit value. 
        
Now we have enough instructions to perform some
      computation.  Let us try some
      simple program in the assembly language of Z0.
We assign r1, r2, r3 
        to B, C and D. 
mvi 0              
          ;  ac = 0 add r2           
            ;  ac = ac
        + r2 add r3             
          ;  ac = ac + r3 put r1             
          ;  r1 = ac stopEach instruction has a 8-bit code. 
        We assign them as follows:
1 add,  2 sub, 
        3 inc,  4 dec, 
        5 mov,  6 mvi, 
        7 --,  8 put,  
        
9 eq,  10
      ne,  11 lt,  12 le, 
        13 gt,  14 ge, 
        15 z,   16 jmp, 
        17 jt,  18 jf, 
        19 stopWe can write the above program in “machine code” as
      follows.  Assume we start the
      program at location 0 and we write down each instruction as
      opcode,operand.
Address   
        instruction
0              
              6,0         
          mvi 0
        1              
              1,2         
          add r2
        2              
              1,3         
          add r3
        3              
              8,1         
          put r1
        4              
              19,0        
          stopPseudo code
i = 1s = 0while i <= 10      s
        = s + i      i
        = i + 1Z0 assembly language
Let r1 be i, r2 s, r3 10
mvi 10put r3mvi 1put r1mvi 0put r2   :loopmov r1le r3              
          ;  i <= 10jf  exitmov r2add r1put r2             
          ;  s = s + iinc r1              ;  
          i = i + 1jmp loop   :exitstopNotice that we use “label” such as “loop” and “exit” to
      designate the location.  We
      use the prefix “:” to signify the labels but no prefix when they are used
      in the instructions. They are used with jump instructions.  Again
      we write down machine code here:
Address   Instruction
0              
          6,10       
          mvi 101              
          8,3        
          put r32              
          6,1        
          mvi 13              
          8,1        
          put r14              
          6,0     
             mvi 05              
          8,2        
          put r2        :loop6              
          5,1
                  mov r17              
          12,3       
          le r3           
          ;  i <= 108              
          18,14      
          jf  exit9              
          5,2        
          mov r210          
             1,1      
            add r111             
          8,2    
              put r2          
          ;  s = s + i12       
                3,1        
          inc r1          
          ;   i = i + 113             
          16,6       
          jmp loop        :exit14         
              19,0       
          stopNote that the labels become the real address. 
        “loop” is the address 6. “exit” is the address 14. 
        The “assembler” is the program that performs the translation of
      “assembly” language into machine codes. The assembler can handle “label”
      automatically.
Let numbers be B, C, D
                       
          B > C           
          Yes
                                   
          No         
          B > D                        
          C > D      
              Yes
                   No
                      
          Yes
                     No max is B     
          max is D       
          max is C      
          max is DLet r1 be B, r2 C, r3 D, r4 max
    mov r1    gt r2        
          ; B > C    jf no1    mov r1    gt r3        
          ; B > D    jf  no2    mov r1    put r4       
          ;  max = B    jmp exit:no2    mov  r3    put r4       
          ; max = D    jmp exit:no1    mov r2    gt r3        
          ; C > D    jf no3    mov r2    put r4    
             ; max = C    jmp exit:no3    mov r3    put r4 
                ; max = D:exit      stopYou will probably notice by now that programming in
      machine language (assembly language) is simple but it is tedious. 
        In fact, machine language is the simplest computer language (you
      opinion may be different from mine).
To extend the storage to main memory, we need
      additional instructions to move data between registers and memory.
ld ads                
          ;   ac =
        M[ads] st ads                
          ;   M[ads] =
        acldd r1             
             ;  
          ac = M[r1]std r1                
          ;   M[r1] = acwith these encoding
20 ld, 21 st, 
          22 ldd,  23 stdNow it is time to talk about “addressing space”. 
        The amount of memory that can be “directly” access by an
      instruction depends on the number of bit of argument in the instruction. 
        In our machine, it is 24 bits. Therefore Z0 has 16 M words memory
      (each word is 32 bits).  This
      is comparable to a 64 Mbytes of conventional RAM we have in our present
      laptop machine.  We have
      “direct” addressing and “indirect” addressing. 
        In direct address, the argument is used to locate the “address”
      directly, for example, ld 100 will access the memory at
      location 100.  The indirect
      address, the value of a register is used as the address (this is called an
      effective address).  In fact,
      a register has 32-bit value so theoretically we can use indirect address
      of our machine to address the main memory as large as 16G bytes.
Now let us program with some data structure. 
        The most frequently used data structure is Array. Indirect
      addressing is used to perform indexing of an array. 
        We can access to the value of an element as follows.  Let
      ax[.] be an array.  An index
      is in r1.  The base address
      (the first location where ax resides) is in r2.
C = ax[i] 
      can be written as   
      ; let r2 be &ax, r1 be i, r3 be C
mov r2       
          ;  ac = iadd r1       
          ;  ac = &ax +
        i, compute effective addressput r1
        ldd r1       
          ; get ax[i]  into
        acput r3       
        ; C = ax[i]Using this access method, you can write a program to
      sum all elements in an array.  Let
      us see one more example of storing a value to an array. 
        How to do this    
        ax[i] = C
Let r2 be &ax, r1 be i, r3 be C
mov r2        
          ;  ac = iadd r1        
          ;  ac = &ax +
        i, compute effective addressput r1
        mov r3     
             ;  get
        Cstd r1        
          ;  ax[i] = C
        
      
Creating function
In a high level language, we can write a modular
      program
      that reuses its component. This is achieved by packaging the often use
      part
      into a “function” (or “procedure” or “method”). 
      In order for a function to return to its caller, we need to store
      the
      “return address” in a special data structure, usually implemented as a
      “stack”.  The Z0 has an
      implicit stack
      for this purpose (with the depth of 8). This stack is not accessible to
      programmers.  We need two more
      instructions to do a function call:
    call ads      
        ;  next pc ->
      stack; jump to ads    ret           
          ; 
        stack -> pc
    
    Example 4 
        Calling a function, passing parameters on
      registers.
Let r2 x, r3 b, we pass a to x via r2 and keep return
      value
      in r0
:double
          mov r2
          add r2       
                ;
      result in r0
          ret
      :main
          mvi 3
          put r2          
        ; pass 3 to x
          call double
          put r3          
        ; store result in b
       
          stop
Enjoy simple machine coding!