1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# Simple example of functions in ASM, following System V ABI
# and C calling convention
# Everything is stored in registers, so, we have nothing in data section
.section .data
.section .text
.globl _start
_start:
pushq $3 # Second argument
pushq $2 # First argument
call power # call function power()
addq $16, %rsp # Remove arguments from the stack
# Could have popped'em, but we don't
# need them anymore, so, just move
# the stack pointer back
pushq %rax # Save return value of power()
# Call power () again
pushq $2 # Push second argument
pushq $5 # Push first argument
call power
addq $16, %rsp # Move stack pointer back
popq %rbx # Second answer is already in %eax
# (returned from power), first answer
# was pushed into the stack before, so,
# just pop it into %ebx.
addq %rax, %rbx # Sum up both results (and %ebx is already the
# exit()'s return value
# Call exit()
movq $1, %rax
int $0x80
####################
# #
# Function power() #
# #
####################
# Remember the return address (where the program should keep executing after
# function return), is also pushed into the stack by the 'call' command.
# Remember, in x86_64 architecture, the Stack grows 'downwards', so, every time
# we want to look back in the stack, we need to add to the current stack
# pointer, other than subtract.
# Ex:
# 56 <- stack 'bottom'
# 48 pushq
# 40 pushq
# 32 <- %rsp (top of the stack)
#Tread symbol 'power' as a function
.type power,@function
power:
pushq %rbp
movq %rsp, %rbp
movq 16(%rbp), %rcx # Holds the Base number. 16 because:
# Current %rsp (pushq %rbp) plus the
# implicit return address pushed by
# the call command
movq 24(%rbp), %rbx # Holds the power (pushed first before
# function call
movq %rcx, %rax
loop:
cmpq $1, %rbx
je return
imul %rcx, %rax # The result is already stored in %rax
decq %rbx
jmp loop
return:
movq %rbp, %rsp
popq %rbp
ret
|