# 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