sp project #1 - skkuarcs.skku.edu/pmwiki/uploads/courses/computerarchitectures/calc... · make...
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