copyright 2014 – noah mendelsohn um macro assembler functions noah mendelsohn tufts university...

47
Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: [email protected] Web: http:// www.cs.tufts.edu/~noah COMP 40: Machine Structure and Assembly Language Programming (Fall 2014)

Upload: sage-mincer

Post on 14-Dec-2015

222 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

Copyright 2014 – Noah Mendelsohn

UM Macro AssemblerFunctions

Noah MendelsohnTufts UniversityEmail: [email protected]: http://www.cs.tufts.edu/~noah

COMP 40: Machine Structure and

Assembly Language Programming (Fall 2014)

Page 2: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn3

Reviewx86-64 Standard Function

Linkage

Page 3: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Why have a standard AMD 64 “linkage” for calling functions? (Review)

Functions are compiled separately and linked together

We need to standardize enough that function calls can be freely mixed

We may “cheat” when caller and callee are in the same source file

4

Page 4: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Function calls on Linux/AMD 64

Caller “pushes” return address on stack

Where practical, arguments passed in registers

Exceptions:

– Structs, etc.

– Too many

– What can’t be passed in registers is at known offsets from stack pointer!

Return values

– In register, typically %rax for integers and pointers

– Exception: structures

Each function gets a stack frame

– Leaf functions that make no calls may skip setting one up

Caller vs. callee saved registers

5

Page 5: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

AMD 64 The stack – general case (review)

6

Before call

????%rsp

Arguments

Return address

After callq

%rsp

Arguments

%rsp

If callee needs frame

????Return address

Args to next call?

Callee vars

sub $0x{framesize},%rsp

Arguments

fram

esize

Page 6: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

AMD 64 arguments/return values in registers

7

Arguments and return values passed in registers when types are suitable and when there aren’t too many

Return values usually in %rax, %eax, etc.

Callee may change these and some other registers!

MMX and FP 87 registers used for floating point

Read the specifications for full details!

Operand Size

Argument Number

1 2 3 4 5 6

64 %rdi %rsi %rdx %rcx %r8 %r9

32 %edi %esi %edx %ecx %r8d %r9d

16 %di %si %dx %cx %r8w %r9w

8 %dil %sil %dl %cl %r8b %r9b

Page 7: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

fact:.LFB2: pushq %rbx.LCFI0: movq %rdi, %rbx movl $1, %eax testq %rdi, %rdi je .L4 leaq -1(%rdi), %rdi call fact imulq %rbx, %rax.L4: popq %rbx ret

AMD 64 Factorial Revisited

8

int fact(int n){ if (n == 0) return 1; else return n * fact(n - 1);}

Page 8: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn9

The UMASMStandard Function Linkage

Page 9: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Why have a standard UMASM function linkage?

Functions are compiled separately and linked together

We need to standardize enough that function calls can be freely mixed

It’s tricky, so doing it the same way every time minimizes bugs and makes code clearer

We may “cheat” when caller and callee are in the same source file

10

Page 10: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Summarizing calling conventions (review)

r0 is always 0 (points to segment 0, used for goto and for the call stack)

r1 is the return-address register and the result register

r2 is the stack pointer and must have same value after return (nonvolatile)

r3, r4 are nonvolatiles

r5 is a helpful volatile register (good to copy return address)

r6, r7 are volatile and are normally .temps (but up to each procedure)

Arguments are on the stack, with first argument at the “bottom” (where r2 points)

11

EXCEPT FOR VOLATILES AND RESULT REGISTERCALLEE MUST LEAVE REGISTERS AND STACK UNCHANGED!

Page 11: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Startup code with stack (REVIEW)

Goals of startup code:

– Set up useful registers

12

init (instructions)

start

.section init

.temps r6, r7

.section stk

.space 100000endstack:.section init.zero r0start: r0 := 0 r2 := endstack goto main linking r1 halt

Page 12: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Startup code with stack (REVIEW)

Goals of startup code:

– Set up useful registers

13

init (instructions)

start

.section init

.temps r6, r7

.section stk

.space 100000endstack:.section init.zero r0start: r0 := 0 r2 := endstack goto main linking r1 halt

Page 13: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Startup code with stack (REVIEW)

Goals of startup code:

– Set up useful registers

– Set up a stack

14

init (instructions)

start

stk10000 words

endstack(r2)

.section init

.temps r6, r7

.section stk

.space 100000endstack:.section init.zero r0start: r0 := 0 r2 := endstack goto main linking r1 halt

Page 14: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Startup code with stack (REVIEW)

Goals of startup code:

– Set up useful registers

– Set up a stack

– Let UMASM know about useful registers

15

init (instructions)

start

stk10000 words

endstack(r2)

.section init

.temps r6, r7

.section stk

.space 100000endstack:.section init.zero r0start: r0 := 0 r2 := endstack goto main linking r1 halt

Page 15: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Startup code with stack (REVIEW)

Goals of startup code:

– Set up useful registers

– Set up a stack

– Let UMASM know about useful registers

– Invoke or drop through to program code

16

init (instructions)

start

stk10000 words

endstack(r2)

.section init

.temps r6, r7

.section stk

.space 100000endstack:.section init.zero r0start: r0 := 0 r2 := endstack goto main linking r1 halt

Page 16: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Summarizing calling conventions

r0 is always 0 (points to segment 0, used for goto and for the call stack)

r1 is the return-address register and the result register

r2 is the stack pointer and must have same value after return (nonvolatile)

r3, r4 are nonvolatiles

r5 is a helpful volatile register (good to copy return address)

r6, r7 are volatile and are normally .temps (but up to each procedure)

Arguments are on the stack, with first argument at the “bottom” (where r2 points)

17

EXCEPT FOR VOLATILES AND RESULT REGISTERCALLEE MUST LEAVE REGISTERS AND STACK UNCHANGED!

Page 17: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn18

Calling a Function with No Arguments

Page 18: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Calling a function with no arguments

19

r1 := return_addr // Offset in seg 0 r7 := somefunc // Offset in seg 0 goto *r7 in program m[r0] // Call the functionreturn_addr: // Function returns here …back in caller…

call somefunc();

Page 19: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Calling a function with no arguments

20

r1 := return_addr // Offset in seg 0 r7 := somefunc // Offset in seg 0 goto *r7 in program m[r0] // Call the functionreturn_addr: // Function returns here …back in caller…

call somefunc();Use of r1 for return address is

required

Page 20: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Calling a function with no arguments

21

r1 := return_addr // Offset in seg 0 r7 := somefunc // Offset in seg 0 goto *r7 in program m[r0] // Call the functionreturn_addr: // Function returns here …back in caller…

call somefunc();

Use of r7 for function address is programmer choice

Page 21: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Calling a function with no arguments

22

r1 := return_addr // Offset in seg 0 r7 := somefunc // Offset in seg 0 goto *r7 in program m[r0] // Call the functionreturn_addr: // Function returns here …back in caller…

call somefunc();

goto somefunc linking r1 // goto main, setting r1 to the return address

UMASM provides this built-in macro to do the above for you!

Page 22: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Calling a function with no arguments

23

r1 := return_addr // Offset in seg 0 r7 := somefunc // Offset in seg 0 goto *r7 in program m[r0] // Call the functionreturn_addr: // Function returns here …back in caller…

call somefunc();

goto somefunc linking r1 // goto main, setting r1 to the return address

UMASM provides this built-in macro to do the above for you!

Also remember: r1 is both the linking and the result register. If somefunc calls another function, then r1 must be saved.

Page 23: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn24

Organizing Startup Code

Page 24: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Language startup routines

The C language uses a startup/closeup routine called crt0 to prepare arguments and invoke main– Sets up argv and argc– Sets up exception handling– Gathers return/exit value from main– Special purpose versions possible: e.g. gcrt0 used when profiling

So…startup code, run before main(), is shared by all programs. Can we do the same for UMSAM?

– Can we package our UMASM programs into a main() function?

…Yes!

25

Page 25: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

urt0: A reuseable UMASM startup routine

26

.zero r0 .temps r7 .section stk .space 100000 endstack: .section init_ustart: r0 := 0 r2 := endstack goto main linking r1

halt // Finis

urt0.ums

Page 26: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

urt0: A reuseable UMASM startup routine

27

.zero r0 .temps r7 .section stk .space 100000 endstack: .section init_ustart: r0 := 0 r2 := endstack goto main linking r1

halt // Finis

Establish r0 as always containing 0

Page 27: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

urt0: A reuseable UMASM startup routine

28

.zero r0 .temps r7 .section stk .space 100000 endstack: .section init_ustart: r0 := 0 r2 := endstack goto main linking r1

halt // Finis

Build stack and set up r2 as stack pointer

Page 28: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

urt0: A reuseable UMASM startup routine

29

.zero r0 .temps r7 .section stk .space 100000 endstack: .section init_ustart: r0 := 0 r2 := endstack goto main linking r1

halt // Finis

Invoke main() as a function!

Trick:

umasm urt0.ums mainprog.ums otherfile.ums

Concatenates all source files before assembling.

Page 29: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Startup code with stack (REVIEW)

Goals of startup code:

– Set up useful registers

– Set up a stack

– Let UMASM know about register assignments

– Invoke or drop through to user code

30

.section init

.temps r6, r7

.section stk

.space 100000endstack:.section init.zero r0start: r0 := 0 r2 := endstack goto main linking r1 halt

init (instructions)

start

stk10000 words

endstack(r2)

WE’VE NOW MADE A COMMON VERSION OF THIS IN urt0.ums!!

Page 30: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn31

Writing A FunctionThat Takes No Arguments

We will use main() as an example

Page 31: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Pushing and popping (Review)

Push macro

Pop macro

32

.zero r0

.temps r6, r7

push r3 on stack r2r6 := -1 // macro instruction (not shown)r2 := r2 + r6m[r0][r2] := r3

Expands to:

pop r3 off stack r2

r3 := m[r0][r2]r6 := 1r2 := r2 + r6

Expands to:

These instructions can be use to save and restore registers andto put function arguments on the stack!

Page 32: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Our program can go in the “main” function

33

.zero r0 .temps r6,r7

main: push r1 on stack r2 // Address main returns to # Can skip one or both of the next two if registers not needed push r3 on stack r2 // Callee saves non-volatile reg push r4 on stack r2 // Callee saves non-volatile reg

...DO REAL WORK HERE... output "Hello world\n"

pop r4 off stack r2 // restore caller's r4 pop r3 off stack r2 // restore caller's r3 pop r5 off stack r2 // get return address r1 := 0 // EXIT_SUCCESS is the result goto r5

Page 33: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Now our program can go in the “main” function

34

.zero r0 .temps r6,r7

main: push r1 on stack r2 // Address main returns to # Can skip one or both of the next two if registers not needed push r3 on stack r2 // Callee saves non-volatile reg push r4 on stack r2 // Callee saves non-volatile reg

...DO REAL WORK HERE... output "Hello world\n"

pop r4 off stack r2 // restore caller's r4 pop r3 off stack r2 // restore caller's r3 pop r5 off stack r2 // get return address r1 := 0 // EXIT_SUCCESS is the result goto r5

Remember…we’re assuming urt0 has set up

stack and r0

Page 34: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Now our program can go in the “main” function

35

.zero r0 .temps r6,r7

main: push r1 on stack r2 // Address main returns to # Can skip one or both of the next two if registers not needed push r3 on stack r2 // Callee saves non-volatile reg push r4 on stack r2 // Callee saves non-volatile reg

...DO REAL WORK HERE... output "Hello world\n"

pop r4 off stack r2 // restore caller's r4 pop r3 off stack r2 // restore caller's r3 pop r5 off stack r2 // get return address r1 := 0 // EXIT_SUCCESS is the result goto r5

Here’s where our useful work will go.

Page 35: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Now our program can go in the “main” function

36

.zero r0 .temps r6,r7

main: push r1 on stack r2 // Address main returns to # Can skip one or both of the next two if registers not needed push r3 on stack r2 // Callee saves non-volatile reg push r4 on stack r2 // Callee saves non-volatile reg

...DO REAL WORK HERE... output "Hello world\n"

pop r4 off stack r2 // restore caller's r4 pop r3 off stack r2 // restore caller's r3 pop r5 off stack r2 // get return address r1 := 0 // EXIT_SUCCESS is the result goto r5

Return address saved from r1

..but popped into R5

Page 36: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Now our program can go in the “main” function

37

.zero r0 .temps r6,r7

main: push r1 on stack r2 // Address main returns to # Can skip one or both of the next two if registers not needed push r3 on stack r2 // Callee saves non-volatile reg push r4 on stack r2 // Callee saves non-volatile reg

...DO REAL WORK HERE... output "Hello world\n"

pop r4 off stack r2 // restore caller's r4 pop r3 off stack r2 // restore caller's r3 pop r5 off stack r2 // get return address r1 := 0 // EXIT_SUCCESS is the result goto r5

Only save non-volatiles if necessary

Page 37: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Now our program can go in the “main” function

38

.zero r0 .temps r6,r7

main: push r1 on stack r2 // Address main returns to # Can skip one or both of the next two if registers not needed push r3 on stack r2 // Callee saves non-volatile reg push r4 on stack r2 // Callee saves non-volatile reg

...DO REAL WORK HERE... output "Hello world\n"

pop r4 off stack r2 // restore caller's r4 pop r3 off stack r2 // restore caller's r3 pop r5 off stack r2 // get return address r1 := 0 // EXIT_SUCCESS is the result goto r5

umasm urt0.ums hello.ums ...more ums here if needed... > hello

Remember to combine all the pieces when you build

Page 38: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn39

UMASMFunction Arguments

and theCall Stack

Page 39: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

UMASM function arguments (Review)

At entry to a function, the stack must look like this

m[r0][r2 + 0] // first parameter m[r0][r2 + 1] // second parameter m[r0][r2 + 2] // third parameter

The called function may push more data on the stack which will change r2…

…when this happens the parameters will appear to be at larger offsets from the (modified) r2!

40

At function entry

????r2

Third parm

Second parm

First parm

Page 40: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn41

Recursion:Factorial

Page 41: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Can we build UMASM code for this?

42

int fact(int n){ if (n == 0) return 1; else return n * fact(n - 1);}

REMEMBER THE CONTRACT BETWEEN CALLER AND CALLEE!

Page 42: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Summarizing calling conventions

r0 is always 0 (points to segment 0, used for goto and for the call stack)

r1 is the return-address register and the result register

r2 is the stack pointer and must have same value after return (nonvolatile)

r3, r4 are nonvolatiles

r5 is a helpful volatile register (good to copy return address)

r6, r7 are volatile and are normally .temps (but up to each procedure)

Arguments are on the stack, with first argument at the “bottom” (where r2 points)

43

EXCEPT FOR VOLATILES AND RESULT REGISTERCALLEE MUST LEAVE REGISTERS AND STACK UNCHANGED!

Page 43: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Factorial

44

.section init .zero r0 .temp r6,r7

fact: push r1 on stack r2 // save return address push r3 on stack r2 // save nonvolatile register r3 := m[r0][r2 + 2] // first parameter 'n'

// Handle base case: if n == 0 if (r3 == 0) goto base_case

// recursive call r5 := r3 - 1 // OK to step on volatile register push r5 on stack r2 // now (n - 1) is a paraemter goto fact linking r1 // make the recursive call pop stack r2 // pop parameter r1 := r3 * r1 // n * fact(n-1) goto finish_fact

base_case: r1 := 1

finish_fact: // What are invariants here? pop r3 off stack r2 // restore saved register pop r5 off stack r2 // put return address in r5 goto r5

Page 44: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Factorial

45

.section init .zero r0 .temp r6,r7

fact: push r1 on stack r2 // save return address push r3 on stack r2 // save nonvolatile register r3 := m[r0][r2 + 2] // first parameter 'n'

// Handle base case: if n == 0 if (r3 == 0) goto base_case

// recursive call r5 := r3 - 1 // OK to step on volatile register push r5 on stack r2 // now (n - 1) is a paraemter goto fact linking r1 // make the recursive call pop stack r2 // pop parameter r1 := r3 * r1 // n * fact(n-1) goto finish_fact

base_case: r1 := 1

finish_fact: // What are invariants here? pop r3 off stack r2 // restore saved register pop r5 off stack r2 // put return address in r5 goto r5

What are the invariants here?

Page 45: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

fact:.LFB2: pushq %rbx.LCFI0: movq %rdi, %rbx movl $1, %eax testq %rdi, %rdi je .L4 leaq -1(%rdi), %rdi call fact imulq %rbx, %rax.L4: popq %rbx ret

Compare with the AMD 64 version

46

int fact(int n){ if (n == 0) return 1; else return n * fact(n - 1);}

Page 46: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Main program to call factorial

47

void main(void){ for (int i = 10; i != 0; i--) { print_d(i); puts("! == "); print_d(fact(i)); putchar('\n'); } return EXIT_SUCCESS;}

Page 47: Copyright 2014 – Noah Mendelsohn UM Macro Assembler Functions Noah Mendelsohn Tufts University Email: noah@cs.tufts.edunoah@cs.tufts.edu Web: noahnoah

© 2010 Noah Mendelsohn

Main program to call factorial

48

.zero r0 .temps r6,r7 main: push r1 on stack r2 // Address main returns to push r3 on stack r2 // Callee saves non-volatile reg r3 := 10 // Using r3 for i - loop var goto main_testmain_loop: push r3 on stack r2 // Pass i as first arg to function goto print_d linking r1 // Call print_d pop stack r2 // Function leaves arg on stack

output "! == " // puts() is inlined

push r3 on stack r2 // Pass i as first arg to function goto fact linking r1 // Call fact push r1 on stack r2 // Pass fact's return value as arg goto print_d linking r1 // Call print_d r2 := r2 + 2 // pop 2 parameters, 1 for each call output '\n' // putc() inlined --- it's a C macro

r3 := r3 - 1 // i--main_test: if (r3 != 0) goto main_loop // while (i != 0) pop r3 off stack r2 // restore caller's r3 pop r5 off stack r2 // get return address r1 := 0 // EXIT_SUCCESS is the result goto r5 // return