Lecture Notes for
Chapter 2 -- SAL
CS/ECE 354: Machine Organization and Programming
- Purpose:
To allow better concentration in lecture by reducing note-taking pressure
and to provide a study-aid before and after lecture.
- Disclaimers:
(a) I will not follow these notes exactly in class.
(b) Students are responsible for what I say in class.
(c) Reading these notes is not a substitute for attending lecture.
(d) These notes probably contain errors.
- Acknowledgements:
These notes are derived from the notes of Karen Miller, Deb Deppeler,
and David Wood, sometimes with substantial and sometimes with trivial changes. Thanks!
- Last updated:
Wednesday, November 14, 2001
*******************************************************************
* Students should read UPDATED Chapter 2 handout from web page, *
* which is more up to date than Chapter 2 in the textbook. *
*******************************************************************
MOTIVATION for SAL:
hiding the details of MAL, MIPS asm. lang. (on purpose!)
SAL code will look more like HLL code -- to make student's transition
easier.
Introducing one more level of abstraction in order to postpone
discussion of several topics.
HLL SAL assembly machine code
each HLL statement maps into 1 or MORE SAL instructions
each SAL instruction maps into 1 or MORE MAL instructions
for this course, there is actually one more layer that
students will be given
HLL SAL MAL TAL MIPS RISC machine code
SAL
A subset of the functionality of most high level languages --
no records/structures
no formal arrays (see chapter 7 for their implementation)
What is required by a programming language?
declarations
arithmetic operations
conditional execution (if then else)
looping control structures
communication w/user. . .(write statement)
About SAL:
-- one instruction, declaration per line
-- comments are anything on a line following `#'
(comments may not span lines)
DECLARATIONS
------------
- they give information about how much memory space is needed
- they assign a name to the memory space
SAL has 3 basic types: integer, float (real), character
can build other types out of these,
for example, boolean is really an integer with only 2 defined values.
Pascal:
var variablename: type;
C:
type variablename;
SAL:
variablename: type value
type is .word if integer
.byte if character
.float if real (floating point)
value is optional -- it gives the variable an initial value
examples:
flag: .word 0
counter: .word 0
variable3: .word
e: .float 2.71828
uservalue: .byte
letter: .byte 'a'
other useful rules:
-- one declaration per line.
-- default initial value is 0.
DIRECTIVES
----------
a way to give information to the assembler.
- all directives start with `.' (period)
examples:
.byte
.word
.float
.data # identifies the start of the declaration section
# there can be more than 1 .data section in
# a program
.text # identifies where instructions are
# there can be more than 1 .text section in
# a program
.asciiz "a string.\n" # places a string into memory
# and null terminates the string.
.ascii "new string." # places a string into memory
# WITHOUT null termination.
ARITHMETIC operations
----------------------
SAL Pascal C
move x, y x := y; x = y;
add x, y, z x := y + z; x = y + z;
sub x, y, z x := y - z; x = y - z;
mul x, y, z x := y * z; x = y * z;
div x, y, z x := y div z; x = y / z;
rem x, y, z x := y mod z; x = y % z;
NOTES: 1. the operation result depends on the type of the variables.
2. cannot increase the number of operands.
3. y and/or z can be IMMEDIATES
examples:
move count, 0
mul product, mult1, mult2
add sum, 2, addend
NOTE: there are other instructions that implement boolean functions,
but we don't cover them yet.
GO OVER SIMPLE PROGRAM modified from REVISED Chapter 2 Figure 1 page 7
(and note that (20+13+82)/3 = 38.333...)
-------------------------------------------
avg3.c
-------------------------------------------
/* a simple C program to average 3 integers */
#include <stdio.h>
void main()
{
int avg;
int i1 = 20;
int i2 = 13;
int i3 = 82;
avg = (i1 + i2 + i3) / 3;
printf("%d\n", avg);
}
-------------------------------------------
avg3.s
-------------------------------------------
# a simple SAL program to average 3 integers
.data
avg: .word
i1: .word 20
i2: .word 13
i3: .word 82
.text
__start: add avg, i1, i2
add avg, avg, i3
div avg, avg, 3
put avg
put '\n'
done
-------------------------------------------
Show assembly code
Assembler translates to executable -- machine language
(multiple source files need "linker" -- much later)
To Run
loader puts executable into memory and makes
CPU jump to first instruction or __start:
execute
executing done returns control to OS
Repeat last step to run again -- usually with different data
simp combines all of the above
Explain
# comment follows and end at end of line
.data # data follows
.text # instructions follow
__start: label to start program
done syscall to end program
CONDITIONAL EXECUTION
---------------------
sometimes an instruction (or a set of instructions) should
be executed, and sometimes it (they) shouldn't.
HLL -- simplest form is a go-to. (Always discouraged.)
Pascal if-then-else
(a conditional go-to!)
if (condition) then
statement
else
statement;
C if-then-else
if (condition)
statement;
else
statement;
SAL 'ifs' and 'gotos'
--------------------------------
SAL Pascal
b label goto label;
bltz x, label if x < 0 then goto label;
bgtz x, label if x > 0 then goto label;
blez x, label if x <= 0 then goto label;
bgez x, label if x >= 0 then goto label;
beqz x, label if x = 0 then goto label;
bnez x, label if x <> 0 then goto label;
beq x, y, label if x = y then goto label;
bne x, y, label if x <> y then goto label;
blt x, y, label if x < y then goto label;
bgt x, y, label if x > y then goto label;
ble x, y, label if x <= y then goto label;
bge x, y, label if x >= y then goto label;
EXAMPLE:
--------
Pascal if-then-else:
if (count < 0) then
begin
count := count + 1;
end;
C equivalent:
if (count < 0)
count = count + 1;
SAL equiv to if-then-else:
bltz count, ifstuff
b endif
ifstuff: add count, count, 1
endif: # next program instruction goes here
-- OR --
bgez count, endif
add count, count, 1
endif: # next program instruction goes here
WHICH ONE OF THESE IS BETTER?
Structured loops can be built out of IF's and GOTO's
(test and branch)
EXAMPLES:
---------
while loop example
Pascal:
while ( count > 0 ) do
begin
a := a mod count;
count := count - 1;
end;
BAD STYLE Pascal:
while: if (count <= 0) then goto endwhile;
a := a mod count;
count := count - 1;
goto while;
endwhile:
C:
while (count > 0) {
a = a % count;
count --;
}
SAL:
while: blez count, endwhile
rem a, a, count
sub count, count, 1
b while
endwhile: # next program instruction goes here
repeat loop example
Pascal:
/* do statement until expression is TRUE */
repeat
if (a < b) then
a := a + 1;
if (a > b) then
a := a - 1;
until a = b;
C:
/* do statement while expression is TRUE */
/* when expression is FALSE, exit loop */
do {
if (a < b)
a++;
if (a > b)
a--;
} while( a != b);
SAL:
repeat: bge a, b, secondif
add a, a, 1
secondif: ble a, b, until
sub a, a, 1
until: bne a, b, repeat
while loop example
Pascal:
while (count < limit) and (c = d) do
begin
/* loop's code goes here */
end;
C:
while ( (count < limit) && (c==d) )
{
/* loop's code goes here */
}
SAL:
while: bge count, limit, endwhile
bne c, d, endwhile
# loop's code goes here
b while
endwhile:
for loop example
Pascal:
for i:= 3 to 8 do
begin
a := a + i;
end;
C:
for ( i = 3; i <= 8; i++)
{
a = a + i;
}
SAL:
move i, 3
for: bgt i, 8, endfor
add a, a, i
add i, i, 1
b for
endfor:
COMMUNICATION WITH THE USER (I/O operations)
--------------------------------------------
SAL Pascal
put x write(x);
get x readln(x);
puts 'string' write('string');
SAL doesn't have any oddities about
testing for eoln or eof. A carriage return is just another
character to be read or written. It is '\n'
get has the most irregularities!
---
get intvariable
places first integer variable it "finds" into intvariable,
then throws away the rest of the line.
if the first value read does not match the type requested, then
the value 0 is placed in variable intvariable.
get charvariable
placed the first character variable it has into charvariable
EXAMPLES:
INPUT:
23 abc
-13
1234fgh!
SAL CODE:
get int1 # int1 <- 23
get int2 # int2 <- -13
get int3 # int3 <- 1234
OR:
get char1 # char1 <- '2'
get int1 # int1 <- 3, and throw away rest of line
get char2 # char2 <- ' ', there is a space character before
# the -13
OR:
get char1 # char1 <- '2'
get char2 # char2 <- '3'
get int1 # int1 <- 0, because the first value read (ignoring
# the white space) is not a digit, so the type does
# not match.
So, if you want to get more than one non-character value from
a single line, you must read in character by character, and
convert to whatever form is desired. More about this in
chapter 4.
PROGRAM EXAMPLE:
----------------
# this simple program adds up 2 integers and prints their sum and products.
.data
prompt1: .asciiz "Enter an integer: "
prompt2: .asciiz "Enter a second integer: "
linefeed: .byte '\n'
msg1: .asciiz "The sum of "
msg2: .asciiz " and "
msg3: .asciiz " is "
msg4: .asciiz "The product of "
int1: .word 0
int2: .word 0
sum: .word
product: .word
.text
# get the 2 integers from user
puts prompt1
get int1
put linefeed
puts prompt2
get int2
put linefeed
# calculate the sum and products
add sum, int1, int2
mul product, int1, int2
# print out the sum and products
puts msg1
put int1
puts msg2
put int2
puts msg3
put sum
put linefeed
puts msg4
put int1
puts msg2
put int2
puts msg3
put product
put linefeed
done
Another simple SAL example program (optional)
----------------------------------
# A SAL program to print out a multiplication table
.data
start: .word 0 # entered by user
finish: .word 0 # entered by user
ii: .word # loop induction variable
jj: .word # loop induction variable
product: .word
prompt1: .asciiz "Enter starting value: "
prompt2: .asciiz "Enter ending value: "
newline: .byte '\n'
x_symbol: .byte 'X'
equals: .byte '='
space: .byte ' '
.text
__start: puts prompt1 # get user input
get start
puts prompt2
get finish
move ii, start
for: bgt ii, finish, all_done # nested for loop to print out
move jj, start # the table
nested: bgt jj, finish, next_iter
mul product, ii, jj
# print one line of table
put ii
put space
put x_symbol
put space
put jj
put space
put equals
put space
put product
put newline
add jj, jj, 1
b nested
next_iter: add ii, ii, 1
put newline
b for
all_done: done
PROCEDURES 101
--------------
In main program:
...
y = abs(x); <--call--need a branch
y = y + 1; <--return point/address
...
int abs (x);
int x, y;
{
if (x < 0) {
y = -x;
}
else {
y = x;
}
return(y);
}; <-- return -- branch back
Ignore parameters, simplest SAL:
...
b abs
return: add y,y,1
...
abs: bgez x, nonnegative
sub y, 0, x
b endabs
nonnegative: move y, x
endabs: b return
But what about (add to HLL):
...
... = abs(y,x)
y = y + 1;
x = y*x; <-- new
... = abs(y,x) <-- new
y = y + 2; <-- new
...
Needed: an ADDRESS to return to!
la var1, label
The address implied by label is placed into var1.
Notice difference between address and contents of
the address.
NOTE: var1 must be declared as integer (.word)
label address contents
aa: 103 6
bb: 104 'a'
cc: 105 2001
The SAL instruction
la cc, bb
changes the table above to be:
label address contents
aa: 103 6
bb: 104 'a'
cc: 105 ** 104 **
Change SAL again
returnhere: .word <-- add
...
la returnhere, return <-- add
b abs
return: add y,y,1
mul x,y,x
la returnhere, return2 <-- add
b abs
return2: ...
Change SAL procedure:
abs: bgez x, nonnegative
sub y, 0, x
b endabs
nonnegative: move y, x
endabs: b returnhere <-- change, NOT!
Must be:
endabs: b (returnhere) <-- Parentheses are important
Key ideas
assembly vs execution
SAL language
declatations
arithmetic
conditional
looping
I/O
procedures