Y86-86 Instruction Set Architecture

This document assumes that you are farmiliar with Y86-86 assembly language and its instruction set architecture. If you are not or want to review the Y86-86 architecture, refer to the chapter 4.1 of Bryant book. This document gives you an essential information you should know for Y86-64-SEQ using logisim.

1. Y86-64 Instructions

Figure 4.2 and 4.3 list the instructions of Y86-64-SEQ with its format, size, opcode (first byte), function code (second byte).

_images/fig4.2.png

Figure 4.2

_images/fig4.3.png

Figure 4.2

Variable length instruction

Y86-64-SEQ has instructions with variable size ranging from 1 byte to 10 bytes. For simple implementation, we fix the number of cycles to fetch the instruction with 10 cycles.

Opcode and Function code in the first byte

In first byte of the insturction, it stores opcoe that is an instruction speicifier and function code that indicates specific integer operation (OPq), data movement condition (cmovXX), or branch condition (jXX). OPq RA, RB for an example, two arithmetic (addq and subq) and two logical (andq and xorq) instructions share the same opcode 6 but they have different function code from 0 to 3 (See Figure 4.3).

Register ID in the second byte

If instructions include source and destation registers, they are stored in the second byte of the instruction. First half byte stores the first source operand, and second half byte stores the second source (or destination) operand. If an insturction have a single operand (pushq, popq), then the second half byte store 0xF indicating no register (Figure 4.4).

Immediate Value from the second or third byte to tenth byte.

Instructions with immediate value (irmovq, rmmovq, mrmovq, jXX, call) store their immediate value from second or third byte

2. Practice with Test Program (asum.ys)

The following Y86-86 assembly is an example code from the Y86-64 student distribution from the authors. Execute the following assembly code and update Programer visible state.

Sum of array
 1# Execution begins at address 0
 2  .pos 0
 3  irmovq stack, %rsp          # Set up stack pointer
 4  call main           # Execute main program
 5  halt                        # Terminate program
 6
 7# Array of 4 elements
 8  .align 8
 9array:        .quad 0x000d000d000d
10  .quad 0x00c000c000c0
11  .quad 0x0b000b000b00
12  .quad 0xa000a000a000
13
14main: irmovq array,%rdi
15  irmovq $4,%rsi
16  call sum            # sum(array, 4)
17  ret
18
19# long sum(long *start, long count)
20# start in %rdi, count in %rsi
21sum:  irmovq $8,%r8        # Constant 8
22  irmovq $1,%r9            # Constant 1
23  xorq %rax,%rax           # sum = 0
24  andq %rsi,%rsi           # Set CC
25  jmp     test         # Goto test
26loop: mrmovq (%rdi),%r10   # Get *start
27  addq %r10,%rax       # Add to sum
28  addq %r8,%rdi        # start++
29  subq %r9,%rsi        # count--.  Set CC
30test: jne    loop          # Stop when 0
31  ret                  # Return
32
33# Stack starts here and grows to lower addresses
34  .pos 0x200
35stack:
Programer Visible Status After running asum.yo
  > yis asum.yo
  Stopped in 34 steps at PC = 0x13.  Status 'HLT', CC Z=1 S=0 O=0
  Changes to registers:
  %rax:       0x0000000000000000      0x0000abcdabcdabcd
  %rsp:       0x0000000000000000      0x0000000000000200
  %rdi:       0x0000000000000000      0x0000000000000038
  %r8:        0x0000000000000000      0x0000000000000008
  %r9:        0x0000000000000000      0x0000000000000001
  %r10:       0x0000000000000000      0x0000a000a000a000

  Changes to memory:
  0x01f0:     0x0000000000000000      0x0000000000000055
  0x01f8:     0x0000000000000000      0x0000000000000013