sp project #1 - skkuarcs.skku.edu/pmwiki/uploads/courses/computerarchitectures/calc... · make...

Post on 23-Apr-2018

231 Views

Category:

Documents

6 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Programming Project #1

< assembly calculator >

Goal

Make Calculator Using Assembly Language

Input of Calculator Program is Infix notation.

Implement RPN Evaluation Algorithm using

Assembly Language.

Infix Input -> Convert to Postfix -> Evaluate

(C Language) (ASSEMBLY)

2

Infix notation

common arithmetic and logical formula

notation

ex)

2 + 3

2 + 3 * 2

5 + ((1 + 2) * 4) − 3

3

RPN(Reverse Polish Notation)

Postfix Notation

mathematical notation wherein every

operator follows all of its operands

obviates the need for parentheses

ex)

2 3 +

2 3 2 *+

5 1 2 + 4 * + 3 –

4

Convert from Infix notation to RPN

Using “Shunting yard algorithm” by

Dijkstra

We Need : Expression, Output Queue,

Stack

5

Convert from Infix notation to RPN(cont’d) Read the next token from expression while exists

If t == number : Add to Output Queue

If t == operator (o1)

while there is an operator at the top of the stack(o2)

If p(o1) <= p(o2) (When o1 is Left-Associative “+-*/”) OR

If p(o1) < p(o2) (When o1 is Right-Associative “^”)

pop o2 off the stack, onto the output queue

Else Break

push o1 onto the operator stack

p(.) means Precedence

6

Convert from Infix notation to RPN(cont’d)

If t == „(‟ then push it onto the stack

If t == „)‟

Until the token at the top of the stack is a left parenthesis,

pop operators off the stack onto the output queue

Pop the left parenthesis from the stack, but not onto the

output queue

If the stack runs out without finding a left parenthesis, then

there are mismatched parentheses (Error)

7

Convert from Infix notation to RPN(cont’d)

When there are no more tokens to read:

While there are still operator tokens in the stack:

If the operator token on the top of the stack is a

parenthesis, then there are mismatched

parenthesis(Error)

Pop the operator onto the output queue.

Exit

8

Example

5 + ((1 + 2) * 4) − 3

9

Token Action Output Stack

5

Example

5 + ((1 + 2) * 4) − 3

10

Token Action Output Stack

5 Add token to the output 5

+

Example

5 + ((1 + 2) * 4) − 3

11

Token Action Output Stack

5 Add token to the output 5

+ Push 5 +

(

Example

5 + ((1 + 2) * 4) − 3

12

Token Action Output Stack

5 Add token to the output 5

+ Push 5 +

( Push 5 +(

(

Example

5 + ((1 + 2) * 4) − 3

13

Token Action Output Stack

5 Add token to the output 5

+ Push 5 +

( Push 5 +(

( Push 5 +((

1

Example

5 + ((1 + 2) * 4) − 3

14

Token Action Output Stack

5 Add token to the output 5

+ Push 5 +

( Push 5 +(

( Push 5 +((

1 Add token to the output 5 1 +((

+

Example

5 + ((1 + 2) * 4) − 3

15

Token Action Output Stack

5 Add token to the output 5

+ Push 5 +

( Push 5 +(

( Push 5 +((

1 Add token to the output 5 1 +((

+ Push 5 1 +((+

2

Example

5 + ((1 + 2) * 4) − 3

16

Token Action Output Stack

5 Add token to the output 5

+ Push 5 +

( Push 5 +(

( Push 5 +((

1 Add token to the output 5 1 +((

+ Push 5 1 +((+

2 Add token to the output 5 1 2 +((+

)

Example

5 + ((1 + 2) * 4) − 3

17

Token Action Output Stack

) Pop until „(„& Pop „(„ 5 1 2 + +(

*

Example

5 + ((1 + 2) * 4) − 3

18

Token Action Output Stack

) Pop until „(„& Pop „(„ 5 1 2 + +(

* Push 5 1 2 + + ( *

4

Example

5 + ((1 + 2) * 4) − 3

19

Token Action Output Stack

) Pop until „(„& Pop „(„ 5 1 2 + +(

* Push 5 1 2 + + ( *

4 Add token to the output 5 1 2 + 4 + ( *

)

Example

5 + ((1 + 2) * 4) − 3

20

Token Action Output Stack

) Pop until „(„& Pop „(„ 5 1 2 + +(

* Push 5 1 2 + + ( *

4 Add token to the output 5 1 2 + 4 + ( *

) Pop until „(„ & Pop „(„ 5 1 2 + 4 * +

-

Example

5 + ((1 + 2) * 4) − 3

21

Token Action Output Stack

) Pop until „(„& Pop „(„ 5 1 2 + +(

* Push 5 1 2 + + ( *

4 Add token to the output 5 1 2 + 4 + ( *

) Pop until „(„ & Pop „(„ 5 1 2 + 4 * +

- Pop and Push

( „-‟ and „+‟ have same precedence)

5 1 2 + 4 * + -

3

Example

5 + ((1 + 2) * 4) − 3

22

Token Action Output Stack

) Pop until „(„& Pop „(„ 5 1 2 + +(

* Push 5 1 2 + + ( *

4 Add token to the output 5 1 2 + 4 + ( *

) Pop until „(„ & Pop „(„ 5 1 2 + 4 * +

- Pop and Push

( „-‟ and „+‟ have same precedence)

5 1 2 + 4 * + -

3 Add token to the output 5 1 2 + 4 *+ 3 -

End Pop, Pop, Pop 5 1 2 + 4 * +3 -

Evaluate RPN

Algorithm( from wikipedia ) Read the next token from postfix while exists

If t == Number : Push it onto the stack

If t == Operator ( it takes n operands(number) ) pop the top n numbers on the stack

If sizeof(stack) < n : (Error) insufficient operands

Evaluate operator with n operands

Push the result value onto the stack

NO MORE TOKEN Then

If sizeof(stack) == 1 : pop(stack) => RESULT!

If sizeof(stack) > 1 : ERROR

23

Example

5 1 2 + 4 * +3 -

24

Input Operation Stack

5 Push 5

1 Push 5 1

2 Push 5 1 2

+ Add (Pop 2 operands & Push result) 5 3

4 Push 5 3 4

* Multiply (Pop 2 operands & Push result) 5 12

+ Add (Pop 2 operands & Push result) 17

3 Push 17 3

- Subtract (Pop 2 operands & Push result) 14

x86 Architecture

8 GPRs, 6 Segment Regs, 1 Flag Reg and 1 Instruction Pointer

GPRs ( 32bits )

25

name Note

EAX Accumulator register. Used in arithmetic operations

ECX Counter register. Used in shift/rotate instructions

EDX Data register. Used in arithmetic operations and I/O operations

EBX Base register. Used as a pointer to data (located in DS in segmented mode)

ESP Stack Pointer register. Pointer to the top of the stack

EBP Stack Base Pointer register. Used to point to the base of the stack

ESI Source register. Used as a pointer to a source in stream operations

EDI Destination register. Used as a pointer to a destination in stream operations

x86 Architecture ( cont’d )

Each of the GPRs 32 bits Extended Registers

16 Least Significant Bits (LSBs) can be accessed using their unextended parts

Ex. AX, CX, DX, BX, SP, BP, SI, and DI

AX, CX, DX, BX the 8 MSBs

AH, CH, DH, BH

the 8 LSBs AL, CL, DL, BL

26

x86 Architecture ( cont’d )

Little Endian

least significant byte first

Ex. 32bits word 0x1BA583D4 would be

written in memory as :

Two‟s complement representation

http://en.wikibooks.org/wiki/X86_Assembly/X8

6_Architecture

27

D4 83 A5 1B

x86 Assembly/x86 Instructions We should use GNU assembler

There are some differences between x86 assembly and

GNU assembly.

http://sourceware.org/binutils/docs-

2.18/as/i386_002dDependent.html#i386_002dDependent

reference link :

http://sourceware.org/binutils/docs-2.18/as/index.html

http://en.wikibooks.org/wiki/X86_Assembly/X86_Instructions

http://en.wikipedia.org/wiki/X86_instruction_listings

28

Attachments

Decompress: tar –xf proj1.tar (will be available at icampus)

Files : proj1.c eval.s con.c Makefile

proj1.c main routine which accepts user‟s input, call convert function and evalu

ate function and print result.

con.c convert function which transform infix notation to postfix notation.

eval.s declare global error variable.

Evaluation function which calculates postfix expression.

Makefile : auto compilation To compile, type at shell : make

To run, type at shell : ./calc

29

Submitting Project Files compress directory include Makefile, README, proj1.

c, con.c, eval.s files. Send compressed file to TA. The file name should be named as “studentid.tar.gz” You have to implement eval.s using Assembly instructions,

push & pop.

README REAMDE include team members(student-number name) and mis

c.

Anything you want to tell TA about your Program.

Filename : your_stududent_id.tar.gz How to compress : tar cfz studentid.tar.gz proj1

Upload the file in the i-campus website

30

Assembly Programming TIP When you initialize Function/Program, don‟t forget to save Stack

Base Pointer(ebp,esp)

When you declare variables, think size of variable first, than

allocate it at stack. Remember the relative address to ebp. (EX.

ebp – 4 => int a;)

I recommend you to draw a state of stack at every step of

programming, not to spoil other variables address or stack of

another functions.

Consider that some registers are unable to use.

(Some registers that you can‟t use.)

Clean up and save registers when you call another function.

Save return value to EAX before return.

Be careful, not to spoil stack address of another functions.

–ebp, esp-(Avoiding Segmentation Fault)

31

Simple Example

Just copy from infix to postfix

32

# int convert ( const char *infix, char *postfix )

convert:

# -- SETUP

pushl %ebp # save old stack base point

movl %esp, %ebp # save new stack base point

# -- BODY

subl $12, %esp # allocate local variables

# Declare local vaiables

movl $1, -4(%ebp) # int success = 1

movl 8(%ebp), %eax #

movl %eax, -8(%ebp) # char *hand_in = infix

movl 12(%ebp), %eax #

movl %eax, -12(%ebp) # char *hand_out = postfix

Simple Example( cont’d )

.convert_check_next_token:

movl -8(%ebp), %eax # char *temp = hand_in

cmpb $0, (%eax) # compare "*temp" and "'\0'"

jne .convert_handle_current_token # if ( *temp != '\0' )

jmp .convert_no_more_token # otherwise

.convert_handle_current_token:

movl -12(%ebp), %edx # t1 = hand_out

movl -8(%ebp), %eax # t2 = hand_in

movb (%eax), %al # t3 = *t1

movb %al, (%edx) # *t2 = t3

leal -12(%ebp), %eax # load effective address of hand_out

incl (%eax) # hand_out = hand_out + 1

leal -8(%ebp), %eax # load effective address of hand_in

incl (%eax) # hand_in = hand_in + 1

jmp .convert_check_next_token33

Simple Example( cont’d )

.convert_no_more_token:

movl -12(%ebp), %eax

movb $0, (%eax) # *hand_out = '\0'

# -- FINISH

movl -4(%ebp), %eax # return success

leave

ret

34

Simple Example( cont’d )

Evaluate only “+”

35

# int eval ( const char * postfix )

eval:

# -- SETUP

pushl %ebp

movl %esp, %ebp

# -- BODY

subl $8, %esp # allocate local variables

# Declare locar variables

movl $0, -4(%ebp) # sum = 0

movl 8(%ebp), %eax #

movl %eax, -8(%ebp) # hand_in = postifx

Simple Example( cont’d )

.eval_handle_plus_token:

popl %edx #

popl %eax # pop two operands

addl %edx, %eax # eax = eax + edx

pushl %eax # push eax

jmp .eval_handle_common_part

.eval_handle_else_token:

movl -8(%ebp), %eax # t1 = hand_in

movb (%eax), %al # t2 = *hand_in

subb $48, %al # convert from character to integer

movsbl %al, %eax # signed extension

pushl %eax # push eax

36

Simple Example( cont’d )

.eval_handle_common_part:

leal -8(%ebp), %eax # load effective address of hand_in

incl (%eax) # hand_in = hand_in + 1

jmp .eval_check_next_token

.eval_no_more_token:

popl %eax #

movl %eax, -4(%ebp) # sum = value in the stack top

# -- FINISH

movl -4(%ebp), %eax # temporary - return 0

leave

ret

37

top related