Compiling to the Assembly Level - PowerPoint PPT Presentation

1 / 75
About This Presentation
Title:

Compiling to the Assembly Level

Description:

The Assembly level was invented to relieve the programmer of ... Mnemonic. Opcode. ix. If N=1, PC := Oprnd. BRLT. 10000. ix. If N=1 or Z=1, PC := Oprnd. BRLE ... – PowerPoint PPT presentation

Number of Views:36
Avg rating:3.0/5.0
Slides: 76
Provided by: acsC2
Category:

less

Transcript and Presenter's Notes

Title: Compiling to the Assembly Level


1
Compiling to the Assembly Level
  • Chapter 6
  • CIS-2261
  • Foundations in Computer Science

2
Homework Chapter 6
Exercises 1, 4, 6, 8, 10, 11, 16
3
Introduction
  • The Assembly level was invented to relieve the
    programmer of the tedium of programming in binary
  • Now its time to look in more detail at the
    relationship of the level 6 language to the level
    5 language
  • Its time to look at how a compiler might
    translate level 6 programming features into the
    equivalent program at level 5

4
Introduction
  • Need to recognize that there are major
    differences between the two levels that the
    compiler must bridge
  • Level 5 has an absence of extensive data types
    offered by a level 6 language
  • To define an array of structures in assembly
    language requires a partitioning of bits and
    bytes
  • This partitioning is the job of a compiler for
    level 6 programming

5
Introduction
  • Also need to think about how control of execution
    flow is handled at level 5 vice level 6
  • Level 6 (C) has IF, WHILE, DO, FOR, SWITCH, and
    FUNCTION statements that can alter normal
    sequential flow
  • Assembly language is limited by von Neumann
    design to more primitive control statements

6
Introduction
  • Need to make sure we look at how the compiler
    must combine several primitive level 5 control
    statements to execute a single, more powerful
    level 6 control statement!!

7
OVERVIEW
  • Branching Instructions and Flow of Control
  • Stack-Relative Addressing and Procedure Calls
  • Indexed Addressing and Arrays
  • Data Types at Level 5

8
Pep/6 Branching Instructions
Remember the operation of the Branching
Instructions!
Status Bits
Addr Modes
Meaning
Mnemonic
Opcode
ix
If N1 or Z1, PC Oprnd
BRLE
01111
ix
If N1, PC Oprnd
BRLT
10000
ix
If Z1, PC Oprnd
BREQ
10001
ix
If Z0, PC Oprnd
BRNE
10010
ix
If N0, PC Oprnd
BRGE
10011
ix
If N0 and Z0, PC Oprnd
BRGT
10100
ix
If V1, PC Oprnd
BRV
10101
ix
If C1, PC Oprnd
BRC
10110
9
Branching Instructions
  • Each of the branching instructions tests one or
    two of the four status bits
  • Use the results of the test to control flow
  • If the condition is true, take the branch - ie
    place the operand into the PC
  • If the condition is not true, do not take the
    branch - ie continue execution with the next
    instruction

10
Branching Instructions
  • Whether a branch occurs depends on the value of
    the status bits
  • The value of the status bits are affected by the
    execution of other instructions

LOADA num, d BRLT Place
LOADA sets the N and Z bits BRLT tests the N bit
only
Translation If num is negative, take the branch
to Place
11
Branching Instructions
  • Lets take a look at how a compiler would
    translate an if statement from C to Pep/6
    Assembly
  • The program computes the absolute value of an
    integer

12
Program 6.1 - IF Translation
High -Order Language (Source Code) include
ltiostream.hgt int number main() cin gtgt
number if (number lt 0)
number -number cout ltlt number
13
Program 6.1 - IF Translation
Cin translation for a number
High level Statements
IF TEST
Computer the negative
14
Program 6.1 Execution
  • Cin statement translates to DECI
  • cout translates to DECO
  • Assignment statement translates into sequence
    LOADA, NOTA, ADDA, STOREA
  • NOTA and ADDA compute the 2s complement
  • IF translates into LOADA and BRGE
  • LOADA sets the N and Z bits
  • BRGE tests the N bit
  • See TEXT page 201-202 for more detail

15
Flow Control for IF Statement
Level 6 Structure
Resulting Level 5 Structure
Statements 1
Statements 1
IF (Comparison 1 - BRGE)
IF (Comparison 1 - lt 0)
Branch if GE
DO Statements 2
DO Statements 2
Statements 3
Statements 3
Need to bypass some of the code if not negative
16
Optimizing Compiler
  • Previous program appeared to have an extra LOADA
    statement that would not be strictly required
  • Can eliminate the second LOADA this time because
    the value of number is already in the accumulator
  • For an assignment statement, a typical compiler
    will
  • load accumulator
  • evaluate expression
  • store the result

17
Optimizing Compilers
  • To eliminate the extra load in program 6.1 would
    require the compiler to remember the content of
    the accumulator
  • A compiler that can do this (and other things) is
    called an optimizing compiler
  • Thus Optimizing compilers are harder to design
    and generally take longer to compile programs
  • Optimizing or non-optimizing depends on the use

18
More Branching Instructions
  • Lets take a look at how a compiler might compile
    a more complex flow controls statement such as an
    IF/ELSE statement
  • In this case the IF body requires an
    unconditional branch around the else body
  • The compiler must recognize this and build that
    control structure into the assembly language

19
Program 6.2 - IF/ELSE Translation
High -Order Language (Source Code) include
ltiostream.hgt const int limit 100 int
num main() cin gtgt num if (number
gt limit) cout ltlt high else
cout ltlt low
How should the compiler handle this output??
20
Program 6.2 IF/ELSE
  • Program 6.2 does not compare a variables value
    with zero
  • Comparison is to a value not equal to zero
  • How can we handle this at the assembly level?
  • Are there more ways than one to handle this
    comparison?

21
Program 6.2 IF/ELSE
  • At least two ways to do this
  • Use COMPA instruction
  • Use SUBA instruction
  • Which way is best?
  • Think in terms of code efficiency

22
Program 6.2 Using COMPA
Does not destroy the result in the Accumulator
only affects the flags
23
Program 6.2 Using SUBA
Destroys the result in the Accumulator you
have Lost your initial value
24
Flow Control for IF/ELSE Statement
Level 6 Structure
Resulting Level 5 Structure
Statements 1
Statements 1
IF (Comparison 1 - BRLT)
IF (Comparison 1 - lt 0)
Branch if LT
DO Statements 2
Else
DO Output high
DO Statements 3
Branch at END of IF
Statements 4
ELSE DO Output low
END of IF
25
More on Flow Control
  • Have talked about how the IF statement can
    control the execution flow
  • Simple conditional branch used
  • Have talked about how the IF/ELSE statement can
    control the execution flow
  • Still use conditional branch but also have to
    include an unconditional branch to exit out of
    the IF body
  • Lets take a look at how the WHILE statement
    control structure is implemented in assembly

26
Program 6.3 - While Translation
High -Order Language (Source Code) include
ltiostream.hgt Char letter main() cin gtgt
letter while (letter ! )
cout ltlt letter cin gtgt
letter
How should the compiler handle the while??
27
Program 6.3 WHILE Control
  • WHILE is a looping instruction and requires the
    compiler to generate assembly code that
    conditionally branches back to the beginning of a
    loop
  • Where does the compiler put the conditional test
    and branch
  • At the beginning of the loop?
  • At the end of the loop?

28
Program 6.3 WHILE Control
Test at top of while loop
Loop Back to top
29
Flow Control for WHILE Statement
Resulting Level 5 Structure
Level 6 Structure
Statements 1
Statements 1
WHILE (Comparison 1 - BREQ)
WHILE (Comparison 1)
Branch if EQ
Statements 2
Output letter
Statements 3
Branch back to top
Statements 3
30
More on Flow Control
  • Does the compiler always have to put the
    conditional test at the top of the loop?
  • With WHILE yes
  • But can have different control structure for
    DO-WHILE

31
Program 6.4 DO-While Translation
High -Order Language (Source Code) include
ltiostream.hgt Int cop Int driver main() cop
0 driver 40 do cop 25 driver
20 while (cop lt driver)
cout ltlt cop
How should the compiler implement
32
Program 6.4 DO-WHILE
Only need one conditional branch
33
Flow Control for DO-WHILE
Resulting Level 5 Structure
Level 6 Structure
Statements 1
Statements 1
DO
DO
Statements 2
Statements 2
WHILE (Comparison 1)
WHILE (Comparison 1 - BREQ)
Statements 3
Statements 3
34
FOR Statements
  • FOR statements are similar to WHILE statements
    wrt to conditional testing
  • Test at the top of the loop
  • Compiler has to generate code to initialize and
    increment the control variable
  • The FOR statement at level 5 becomes
  • Initialize the control variable
  • Test the control variable
  • Execute the loop body
  • Increment the control variable
  • Branch to the test at the top of the loop
  • This is pretty similar to the WHILE implementation

35
Program 6.5 FOR Translation
High -Order Language (Source Code) include
ltiostream.hgt int i main() for (i 0 i lt 3
i) cout ltlt i ltlt i ltlt endl cout ltlt i
ltlt i ltlt endl
36
Program 6.5 FOR Translation
Test at the top
Loop back to top
37
Flow Control for FOR Statement
Resulting Level 5 Structure
Level 6 Structure
Statements 1
Statements 1
FOR (Comparison 1 - BRGE)
FOR (Comparison 1)
Branch if GE
Statements 2
Statements 2
Statements 3
Branch back to top
Statements 3
38
OVERVIEW
  • Branching Instructions and Flow of Control
  • Stack-Relative Addressing and Procedure Calls
  • Indexed Addressing and Arrays
  • Data Types at Level 5

39
Stack-Relative Addressing
  • So far have talked about direct addressing modes
    and immediate addressing modes
  • What about Stack-Relative addressing modes?
  • Why would we want to have that type of addressing
    mode?

40
Stack-Relative Addressing
  • Need to support methods that will allow us to
    make routine calls and returns
  • Need to use the stack to implement that
    efficiently
  • Use the stack like we use the Program Counter
    only use it to point to data instead of
    instructions
  • Remember the instructions that use the stack
    pointer (chapter 2)
  • JSR
  • RTS

41
Stack-Relative Addressing
  • Compiler will implement procedure calls with the
    JSR instruction
  • JSR pushes the content of the PC onto the top of
    stack and loads the operand into the PC
  • Stack Pointer used to keep track of the top of
    stack
  • JSR implements as
  • SP SP-2
  • MemSP PC
  • PC Operand

42
Stack-Relative Addressing
  • Compiler will implement procedure returns with
    the RTS instruction
  • RTS pops the return address from the top of stack
    and loads the that address into the PC
  • Must readjust the Stack Pointer to new top of
    stack
  • RTS implements as
  • PC MemSP
  • SP SP2
  • Also need to think about how to pass parameters!
  • So far have only talked about a parameter less
    calls
  • Compiler must also handle this over and above
    what it does on JSR and RTS

43
Program 6.7 Procedure Call w/o Parameters
High -Order Language (Source Code) include
ltiostream.hgt Void PrintTri () cout ltlt ltlt
endl cout ltlt ltlt endl cout ltlt ltlt
endl cout ltlt ltlt endl main()
PrintTri() PrintTri() PrintTri()
44
Program 6.7 Procedure Call w/o Parameters
Before first JSR
Mem
CPU
002E
PC
?
0BE4
0BE6
SP
?
0BE6
After first JSR
Mem
CPU
0003
PC
0031
0BE4
0BE4
SP
?
0BE6
45
Stack-Relative Addressing
  • When a program calls a procedure, the calling
    program must allocate storage on the stack for
  • Parameters first
  • Next the return address
  • The Called procedure then allocates storage for
    its local variables

46
Stack-Relative Addressing
  • How does the machine reference the data using the
    Stack Pointer?
  • Stack-Relative Addressing
  • Oprnd MemSP OprndSpec
  • Use the Stack Pointer as a memory address to
    which the operand is added
  • Think of the operand specifier as the offset from
    the top of stack

47
Stack-Relative Addressing
  • Pep/6 has one instruction for manipulating the
    stack pointer
  • ADDSP
  • Add a negative value to the stack pointer to
    allocate storage onto the stack
  • Add a positive value to the stack pointer to
    deallocate storage

48
Program 6.8 - Stack-Relative Addressing
Mem
?
0BE2
?
0BE3
?
0BE4
CPU
?
0BE5
SP
0BE6
?
0BE6
?
Before execution
l
0BE2
a
0BE3
e
0BE4
CPU
r
0BE5
SP
0BE2
?
0BE6
After ADDSP
?
49
Program 6.8 - Stack-Pointer Operations
Mem
0
l
?
-4
1
a
?
-3
e
2
?
-2
CPU
CPU
r
3
?
-1
SP
SP
?
4
0BE6
?
0
0BE2
?
?
Before execution
After ADDSP
To deallocate the stack have to add back because
the allocation process adjusted the stack pointer
to a higher place in memory
50
Stack Operations
  • Lets look at how the stack is used during a
    procedure call

51
Program 6.9
High -Order Language (Source Code) include
ltiostream.hgt int numPts int value int I void
PrintBar (int n) int j for (j 1 j lt n
j) cout ltlt cout ltlt endl main()
cin gtgt numPts for (i 1 i lt numPts
i) cin gtgt value PrintBar
(value)
52
Stack Operations - Procedures
  • The calling routine is responsible for
  • pushing the actual parameters
  • executing the JSR (pushing the return address)
  • The called procedure is responsible for
  • allocating storage for local variables
  • after execution deallocating storage for local
    variables
  • popping the return address (executing RTS)
  • The calling routine must still
  • deallocate storage for actual parameters

53
Program 6.9 - Procedure Call
Allocate Local
Execute Procedure
Deallocate Local
Execute RTS
54
Program 6.9 - Procedure Call
Read in value to pass
Allocate Parameter
Adjust stack pointer
Execute JSR
Deallocate Parameter
55
Stack-Relative Addressing - Functions
  • Addressing for Function Calls are similar to
    Procedure Calls
  • Calling program must
  • Push storage for returned values before actual
    parameters
  • Pop returned values upon return

56
Program 6.10 - Function Call
57
Program 6.10 - Function Call
58
Program 6.10 - Function Call
59
OVERVIEW
  • Branching Instructions and Flow of Control
  • Stack-Relative Addressing and Procedure Calls
  • Indexed Addressing and Arrays
  • Data Types at Level 5

60
Indexed Addressing and Arrays
  • Remember that a variable is referred to by name
    at level 6 but by memory location at level 5
  • How then should we handle manipulation of arrays
  • How about using an Index register to point to the
    right location in memory for an array variable?

61
Program 6.11
  • In the past we have used a brute force method for
    outputting a sequence of characters
  • That is fine for short programs, but not very
    efficient for long programs

62
Program 6.11 - Example
High -Order Language (Source Code) include
ltiostream.hgt main() cout ltlt A long
message.
63
Program 6.11 - Bad Solution
This code is self-modifying - dangerous!!
64
Program 6.11 - Bad Example
  • Why is this a bad example?
  • Not normally a good thing for executing code to
    modify itself during execution
  • Called an IMPURE program
  • LISP is a notable exception
  • Better to use hardware to index through the array

65
Indexed Addressing
  • Use indexed addressing to solve the previous
    problem
  • Remember (YOU WILL SEE AGAIN!)
  • Immediate addressing Oprnd OprndSpec
  • Direct addressing Oprnd MemOprndSpec
  • Stack-relative add Oprnd MemSPOprndSpec
  • Indexed addressing Oprnd MemBX

66
Problem 6.12 - Good Example
Uses indexing method to work through array
Initially acc MemmsgX
67
OVERVIEW
  • Branching Instructions and Flow of Control
  • Stack-Relative Addressing and Procedure Calls
  • Indexed Addressing and Arrays
  • Data Types at Level 5

68
Data Types at Level 5
  • So far we have looked at implementing level 6
    code from the perspective of program instruction
    and control
  • Also need to consider how data is abstracted as
    well
  • At the machine level the only data types are bits
    and bytes
  • The compiler must use its symbol table to achieve
    data abstraction
  • Lets look at how this might be achieved

69
Enumerated Data Types
  • This type lets the programmer give a name to a
    nonnegative integer value
  • The compiler stores the names in a table
  • When the compiler encounters the name later on,
    it substitutes the corresponding value

70
Enumerated Data Types
71
Boolean Data Types
  • Several ways of storing/treating boolean values
    at the assembly level
  • C handles booleans as either true or false
  • Compiler must translate that representation into
    a numerical representation
  • True becomes 0001
  • False becomes 0000

72
Boolean Data Types
  • This approach works well for most of the
    operations
  • AND and OR operators function correctly
  • NOT operator does not
  • To overcome these problems with the NOT operation
  • Assign True the value of FFFF instead of 0001
  • Assign False the value of 0000 as usual
  • Everything now works OK

73
Structure Types
  • Structures are the key to data abstraction at
    Level 6
  • Allows consolidation of variables with primitive
    data types into a single abstract data type
  • The compiler uses the struct construct at level
    6
  • This equates to a contiguous group of bytes at
    the assembly level

74
Pointer Types
  • A pointer at level 6 is a memory address at level
    5
  • Use the pointer concept in C with new
    statements and as references in JAVA
  • Operation is similar to that already described
    but uses something called the heap as opposed to
    the stack

75
END Chapter 6
Write a Comment
User Comments (0)
About PowerShow.com