diff options
| author | Carlos Maiolino <[email protected]> | 2025-07-10 22:55:07 +0200 |
|---|---|---|
| committer | Carlos Maiolino <[email protected]> | 2025-07-10 22:56:55 +0200 |
| commit | d98f46ce647846b0aa30b2e16a30fd4e152a1bf5 (patch) | |
| tree | 267474fcc77cf20b428f6f4c7f768ca09f4cfe0e /PGU/OLD/chapter4 | |
| parent | 869e68986aa8f69af6e7842260a68d1e5c6f796f (diff) | |
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'PGU/OLD/chapter4')
| -rw-r--r-- | PGU/OLD/chapter4/call_power.c | 12 | ||||
| -rw-r--r-- | PGU/OLD/chapter4/factorial.s | 73 | ||||
| -rw-r--r-- | PGU/OLD/chapter4/libpower.s | 48 | ||||
| -rw-r--r-- | PGU/OLD/chapter4/power.s | 90 |
4 files changed, 223 insertions, 0 deletions
diff --git a/PGU/OLD/chapter4/call_power.c b/PGU/OLD/chapter4/call_power.c new file mode 100644 index 0000000..b6bb7e0 --- /dev/null +++ b/PGU/OLD/chapter4/call_power.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +int power(int a, int b); + +int main(void) { + int a = 2; + int b = 6; + + printf("Power == %d\n", power(2, 6)); + + return 0; +} diff --git a/PGU/OLD/chapter4/factorial.s b/PGU/OLD/chapter4/factorial.s new file mode 100644 index 0000000..749f57e --- /dev/null +++ b/PGU/OLD/chapter4/factorial.s @@ -0,0 +1,73 @@ +################################################################## +# Calculate the factorial of a number, using recursive functions # +################################################################## + + +# +# %rbx holds the number to factor +# +.section .data + +.section .text + +.globl _start +_start: + pushq $5 + call factorial2 + addq $8, %rsp # Turn back the stack pointer + # Not really needed here, but good practice + movq %rax, %rbx + movq $1, %rax + int $0x80 + +.type factorial, @function + +# This function is garbage, can be much more clean than this shit. + +factorial: + pushq %rbp # Regular initial function stuff + movq %rsp, %rbp # Save %rbp and reset it to %rsp + + movq 16(%rbp), %rbx # Get the argument passed into %rbx + movq %rbx, %rcx # Copy it to %rcx and decrement it + decq %rcx # here. %rcx will be the next element in the + # factorial. + # + cmpq $1, %rcx # Compare it to 1 and exit if true, we are at + je exit_factorial # the end of the factorial + + pushq %rbx # If not one, save the original argument in the + pushq %rcx # stack and push the next value as argument to + call factorial # the recursive call + popq %rcx # pop value to restore stack pointer + popq %rbx # restore %rbx and multiply it + imul %rax, %rbx # by the result + +exit_factorial: + movq %rbx, %rax # Move the result to %rax + movq %rbp, %rsp # And do standard clean up before + popq %rbp # returning. + ret + +# This is a clean version after extra thought on this + +.type factorial2, @function +factorial2: + pushq %rbp # Basic function setup, save %rbp and + movq %rsp, %rbp # setup it to current %rsp + + movq 16(%rbp), %rax # Get the argument passed into + cmpq $1, %rax # + je factorial2_end # We are at the last element in the factorial + # Just return it + decq %rax + pushq %rax + call factorial2 + movq 16(%rbp), %rbx + imulq %rbx, %rax + +factorial2_end: + movq %rbp, %rsp + popq %rbp + ret + diff --git a/PGU/OLD/chapter4/libpower.s b/PGU/OLD/chapter4/libpower.s new file mode 100644 index 0000000..5172cda --- /dev/null +++ b/PGU/OLD/chapter4/libpower.s @@ -0,0 +1,48 @@ +# 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 + +#################### +# # +# 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) + +.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 + decq %rbx + jmp loop + +return: + movq %rbp, %rsp + popq %rbp + ret diff --git a/PGU/OLD/chapter4/power.s b/PGU/OLD/chapter4/power.s new file mode 100644 index 0000000..fe89eae --- /dev/null +++ b/PGU/OLD/chapter4/power.s @@ -0,0 +1,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 |
