Showing posts with label Assembly. Show all posts
Showing posts with label Assembly. Show all posts

Saturday, January 9, 2010

SPIM print example

# This program takes input from the user and echoes it back

.data
# Constant strings to be output to the terminal
promptInt: .asciiz "Please input an integer: "
resultInt: .asciiz "Next integer is: "
linefeed: .asciiz "\n"
enterkey: .asciiz "Press any key to end program."
.text
main:
# prompt for an integer
li $v0,4 # code for print_string
la $a0,promptInt # point $a0 to prompt string
syscall # print the prompt
# get an integer from the user
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
move $t0,$v0 # move the resulting int to $t0
# compute the next integer
addi $t0, $t0, 1 # t0 <-- t0 + 1
# print out text for the result
li $v0,4 #code for print_string
la $a0,resultInt # point $a0 to result string
syscall # print the result string
# print out the result
li $v0,1 # code for print_int
move $a0,$t0 # put result in $a0
syscall # print out the result
# print out a line feed
li $v0,4 # code for print_string
la $a0,linefeed # point $a0 to linefeed string
syscall # print linefeed
# wait for the enter key to be pressed to end program
li $v0,4 # code for print_string
la $a0,enterkey # point $a0 to enterkey string
syscall # print enterkey
# wait for input by getting an integer from the user (integer is ignored)
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
# All done, thank you!
li $v0,10 # code for exit
syscall # exit program

Registers

By convention, many MIPS registers have special purpose uses. To help clarify this, SPIM defines aliases for each register that represent its purpose. The following table lists these aliases and the commonly accepted uses for the registers.


Register
Number
Usage
zero
0
Constant 0
at
1
Reserved for assembler
v0
2
Used for return values
 from function calls.
v1
3
a0
4
Used to pass arguments to 
procedures and functions.
a1
5
a2
6
a3
7
t0
8
Temporary (Caller-saved, need 
not be saved by called procedure)
t1
9
t2
10
t3
11
t4
12
t5
13
t6
14
t7
15
s0
16
Saved temporary (Callee-saved,
 called procedure must save and restore)
s1
17
s2
18
s3
19
s4
20
s5
21


s6
22
s7
23
t8
24
Temporary (Caller-saved, need not 
be saved by called procedure)
t9
25
k0
26
Reserved for OS kernel
k1
27
gp
28
Pointer to global area
sp
29
Stack pointer
fp
30
Frame pointer
ra
31
Return address for function calls.


SPIM Instruction Set

This document gives an overview of the more common instructions used in the SPIM simulator. See Appendix A of Computer Organization and Design by Hennessy and Patterson for more details.
Overview
The SPIM simulator implements the full MIPS instruction set, as well as a large number of pseudoinstructions that correspond to one or more equivalent MIPS instructions. There are also a small number of system call commands used to interface with the console window of the SPIM simulator. Finally, SPIM renames registers according to commonly used conventions in order to facilitate the readability of programs.
Instructions and PseudoInstructions
The following is an abbreviated list of MIPS instructions and SPIM pseudoinstructions. This list is not complete. Notably missing are all Floating Point and coprocessor instructions.
- Indicates an actual MIPS instruction. Others are SPIM pseudoinstructions.


Instruction Function


add Rd, Rs, Rt Rd = Rs + Rt (signed)
addu Rd, Rs, Rt Rd = Rs + Rt (unsigned)
addi Rd, Rs, Imm Rd = Rs + Imm (signed)
sub Rd, Rs, Rt Rd = Rs - Rt (signed)
subu Rd, Rs, Rt Rd = Rs - Rt (unsigned)
div Rs, Rt lo = Rs/Rt, hi = Rs mod Rt (integer division, signed)
divu Rs, Rt lo = Rs/Rt, hi = Rs mod Rt (integer division, unsigned)
div Rd, Rs, Rt Rd = Rs/Rt (integer division, signed)
divu Rd, Rs, Rt Rd = Rs/Rt (integer division, unsigned)
rem Rd, Rs, Rt Rd = Rs mod Rt (signed)
remu Rd, Rs, Rt Rd = Rs mod Rt (unsigned)
mul Rd, Rs, Rt Rd = Rs * Rt (signed)
mult Rs, Rt hi, lo = Rs * Rt (signed, hi = high 32 bits, lo = low 32 bits)
multu Rd, Rs hi, lo = Rs * Rt (unsigned, hi = high 32 bits, lo = low 32 bits)


and Rd, Rs, Rt Rd = Rs • Rt
andi Rd, Rs, Imm Rd = Rs • Imm
neg Rd, Rs Rd = -(Rs)
nor Rd, Rs, Rt Rd = (Rs + Rt)’
not Rd, Rs Rd = (Rs)’
or Rd, Rs, Rt Rd = Rs + Rt
ori Rd, Rs, Imm Rd = Rs + Imm
xor Rd, Rs, Rt Rd = Rs Rt
xori Rd, Rs, Imm Rd = Rs Imm
sll Rd, Rt, Sa Rd = Rt left shifted by Sa bits
sllv Rd, Rs, Rt Rd = Rt left shifted by Rs bits
srl Rd, Rs, Sa Rd = Rt right shifted by Sa bits
srlv Rd, Rs, Rt Rd = Rt right shifted by Rs bits
move Rd, Rs Rd = Rs
mfhi Rd Rd = hi
mflo Rd Rd = lo
li Rd, Imm Rd = Imm
lui Rt, Imm Rt[31:16] = Imm, Rt[15:0] = 0
lb Rt, Address(Rs) Rt = byte at M[Address + Rs] (sign extended)
sb Rt, Address(Rs) Byte at M[Address + Rs] = Rt (sign extended)
lw Rt, Address(Rs) Rt = word at M[Address + Rs]
sw Rt, Address(Rs) Word at M[Address + Rs] = Rt
slt Rd, Rs, Rt Rd = 1 if Rs < Rt, Rd = 0 if Rs ≥ Rt (signed)
slti Rd, Rs, Imm Rd = 1 if Rs < Imm, Rd = 0 if Rs ≥ Imm (signed)
sltu Rd, Rs, Rt Rd = 1 if Rs < Rt, Rd = 0 if Rs ≥ Rt (unsigned)
beq Rs, Rt, Label Branch to Label if Rs == Rt
beqz Rs, Label Branch to Label if Rs == 0
bge Rs, Rt, Label Branch to Label if Rs ≥ Rt (signed)
bgez Rs, Label Branch to Label if Rs ≥ 0 (signed)
bgezal Rs, Label Branch to Label and Link if Rs ≥ Rt (signed)
bgt Rs, Rt, Label Branch to Label if Rs > Rt (signed)
bgtu Rs, Rt, Label Branch to Label if Rs > Rt (unsigned)
bgtz Rs, Label Branch to Label if Rs > 0 (signed)
ble Rs, Rt, Label Branch to Label if Rs ≤ Rt (signed)
bleu Rs, Rt, Label Branch to Label if Rs ≤ Rt (unsigned)
blez Rs, Label Branch to Label if Rs ≤ 0 (signed)
bgezal Rs, Label Branch to Label and Link if Rs ≥ 0 (signed)
bltzal Rs, Label Branch to Label and Link if Rs < 0 (signed)
blt Rs, Rt, Label Branch to Label if Rs < Rt (signed)
bltu Rs, Rt, Label Branch to Label if Rs < Rt (unsigned)
bltz Rs, Label Branch to Label if Rs < 0 (signed)
bne Rs, Rt, Label Branch to Label if Rs ≠ Rt
bnez Rs, Label Branch to Label if Rs ≠ 0
j Label Jump to Label unconditionally
jal Label Jump to Label and link unconditionally
jr Rs Jump to location in Rs unconditionally
jalr Label Jump to location in Rs and link unconditionally 

System Calls

In order to perform I/O with the console, SPIM provides a small library of system calls. In general, system calls are set up by placing a system call in register $v0, and any arguments in register $a0 and $a1. Returned values are placed in register $v0. See the table and the example program below for usage.


Service
System Call Code
Arguments
Result
Print_int
1
$a0 = integer


Print_float
2
$f12 = float


Print_double
3
$f12 = double


Print_string
4
$a0 = string


Read_int
5


Integer (in $v0)
Read_float
6


Float (in $f0)
Read_double
7


Double (in $f0)
Read_string
8
$a0 = buffer, $a1 = length


Sbrk
9
$a0 = amount
Address (in $v0)
exit
10






# This program takes input from the user and echoes it back


.data
# Constant strings to be output to the terminal
promptInt: .asciiz "Please input an integer: "
resultInt: .asciiz "Next integer is: "
linefeed: .asciiz "\n"
enterkey: .asciiz "Press any key to end program."


.text
main:
# prompt for an integer
li $v0,4 # code for print_string
la $a0,promptInt # point $a0 to prompt string
syscall #print the prompt
# get an integer from the user
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
move $t0,$v0 # move the resulting int to $t0
# compute the next integer
addi $t0, $t0, 1 # t0 <-- t0 + 1
# print out text for the result
li $v0,4 #code for print_string
la $a0,resultInt # point $a0 to result string
syscall # print the result string
# print out the result
li $v0,1 # code for print_int
move $a0,$t0 # put result in $a0
syscall # print out the result
# print out a line feed
li $v0,4 # code for print_string
la $a0,linefeed # point $a0 to linefeed string
syscall # print linefeed
# wait for the enter key to be pressed to end program
li $v0,4 # code for print_string
la $a0,enterkey # point $a0 to enterkey string
syscall # print enterkey
# wait for input by getting an integer from the user (integer is ignored)
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
# All done, thank you!
li $v0,10 # code for exit
syscall # exit program

Instruction

In computer science, an instruction is a single operation of a processor defined by an instruction set architecture. In a broader sense, an "instruction" may be any representation of an element of an executable program, such as a bytecode.
On traditional architectures, an instruction includes an opcode specifying the operation to be performed, such as "add contents of memory to register", and zero or more operand specifiers, which may specify registers, memory locations, or literal data. The operand specifiers may have addressing modes determining their meaning or may be in fixed fields.

Operand


An operand is a quantity on which an operation is performed. The following arithmetic expression shows an example of operators and operands:
3 + 6 = 9
In the above example, '+' is the symbol for the operation called addition. The operand '3' is one of the inputs (quantities) followed by the addition operator, and the operand '6' is the other input necessary for the operation. The result of the operation is 9. (The number '9' is also called the sum of the addend, 3 and 6.)
An operand, then, is also referred to as "one of the inputs (quantities) for an operation".

Illegal opcode

An Illegal Opcode, also called an Undocumented Instruction, is an instruction to a CPU that is not mentioned in any official documentation released by the CPU's designer or manufacturer, which nevertheless has an effect. Illegal opcodes were common on older CPUs designed during the 1970s, such as the MOS Technology 6502, Intel 8086 and the Zilog Z80. They exist as a side-effect of the wiring of transistors in the CPU, and usually combine functions of the CPU that were not intended to be combined.

Opcode

In computer technology, an opcode (operation code) is the portion of a machine language instruction that specifies the operation to be performed. Their specification and format are laid out in the instruction set architecture of the processor in question (which may be a general CPU or a more specialized processing unit). Apart from the opcode itself, an instruction normally also has one or more specifiers for operands (i.e. data) on which the operation should act, although some operations may have implicit operands, or none at all. There are instruction sets with nearly uniform fields for opcode and operand specifiers, as well as others (the x86 architecture for instance) with a more complicated, varied length structure.
Depending on architecture, the operands may be register values, values in the stack, other memory values, I/O ports, etc, specified and accessed using more or less complex addressing modes. The types of operations include arithmetics, data copying, logical operations, and program control, as well as special instructions (such as CPUID and others).

Typed Assembly language

In computer science, a typed assembly language (TAL) is an assembly language that is extended to include a method of annotating the datatype of each value that is manipulated by the code. These annotations can then be used by a program (type checker) that processes the assembly language code in order to analyse how it will behave when it is executed. Specifically, such a type checker can be used to prove the type safety of code that meets the criteria of some appropriate type system.
Typed assembly languages usually include a high-level memory management system based on a garbage collection.
A typed assembly language with a suitably expressive type system can be used to enable the safe execution of untrusted code without using an intermediate representation like bytecode, allowing features similar to those currently provided by virtual machine environments like Java and .NET.

Instruction set

An instruction set is a list of all the instructions, and all their variations, that a processor (or in the case of a virtual machine, an interpreter) can execute.
Instructions include:
Arithmetic such as add and subtract
Logic instructions such as and, or, and not
Data instructions such as move, input, output, load, and store
Control flow instructions such as goto, if ... goto, call, and return.
An instruction set, or instruction set architecture (ISA), is the part of the computer architecture related to programming, including the native data types, instructions, registers, addressing modes, memory architecture, interrupt and exception handling, and external I/O. An ISA includes a specification of the set of opcodes (machine language), the native commands implemented by a particular processor.
Instruction set architecture is distinguished from the microarchitecture, which is the set of processor design techniques used to implement the instruction set. Computers with different microarchitectures can share a common instruction set. For example, the Intel Pentium and the AMD Athlon implement nearly identical versions of the x86 instruction set, but have radically different internal designs.
This concept can be extended to unique ISAs like TIMI (Technology-Independent Machine Interface) present in the IBM System/38 and IBM AS/400. TIMI is an ISA that is implemented as low-level software and functionally resembles what is now referred to as a virtual machine. It was designed to increase the longevity of the platform and applications written for it, allowing the entire platform to be moved to very different hardware without having to modify any software except that which comprises TIMI itself. This allowed IBM to move the AS/400 platform from an older CISC architecture to the newer POWER architecture without having to recompile any parts of the OS or software associated with it. Nowadays there are several open source Operating Systems which could be easily ported on any existing general purpose CPU, because the compilation is the essential part of their design (e.g. new software installation).

Assembly language

Assembly languages are a family of low-level languages for programming computers, microprocessors, microcontrollers, and other (usually) integrated circuits. They implement a symbolic representation of the numeric machine codes and other constants needed to program a particular CPU architecture. This representation is usually defined by the hardware manufacturer, and is based on abbreviations (called mnemonics) that help the programmer remember individual instructions, registers, etc. An assembly language is thus specific to a certain physical or virtual computer architecture (as opposed to most high-level languages, which are usually portable).
A utility program called an assembler is used to translate assembly language statements into the target computer's machine code. The assembler performs a more or less isomorphic translation (a one-to-one mapping) from mnemonic statements into machine instructions and data. This is in contrast with high-level languages, in which a single statement generally results in many machine instructions.
Many sophisticated assemblers offer additional mechanisms to facilitate program development, control the assembly process, and aid debugging. In particular, most modern assemblers include a macro facility (described below), and are called macro assemblers.