summaryrefslogtreecommitdiff
path: root/PGU/OLD
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-10 22:55:07 +0200
committerCarlos Maiolino <[email protected]>2025-07-10 22:56:55 +0200
commitd98f46ce647846b0aa30b2e16a30fd4e152a1bf5 (patch)
tree267474fcc77cf20b428f6f4c7f768ca09f4cfe0e /PGU/OLD
parent869e68986aa8f69af6e7842260a68d1e5c6f796f (diff)
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'PGU/OLD')
-rw-r--r--PGU/OLD/asm/exit.s17
-rw-r--r--PGU/OLD/asm/max.c27
-rw-r--r--PGU/OLD/asm/max.s39
-rw-r--r--PGU/OLD/asm/maximumbin0 -> 1120 bytes
-rw-r--r--PGU/OLD/asm/maximum.s14
-rw-r--r--PGU/OLD/chapter3/exitbin0 -> 704 bytes
-rw-r--r--PGU/OLD/chapter3/exit.s70
-rw-r--r--PGU/OLD/chapter3/max.s42
-rw-r--r--PGU/OLD/chapter3/min.s52
-rw-r--r--PGU/OLD/chapter4/call_power.c12
-rw-r--r--PGU/OLD/chapter4/factorial.s73
-rw-r--r--PGU/OLD/chapter4/libpower.s48
-rw-r--r--PGU/OLD/chapter4/power.s90
13 files changed, 484 insertions, 0 deletions
diff --git a/PGU/OLD/asm/exit.s b/PGU/OLD/asm/exit.s
new file mode 100644
index 0000000..b1ef45b
--- /dev/null
+++ b/PGU/OLD/asm/exit.s
@@ -0,0 +1,17 @@
+.section .data
+
+.section .text
+
+.globl _start
+
+_start:
+
+ # %eax should contain syscall number
+ # to be executed (exit syscall num: 1)
+ movl $1, %eax
+
+ # %ebx contains syscall argument
+ movl $5, %ebx
+
+ #Call syscall interrupt
+ int $0x80
diff --git a/PGU/OLD/asm/max.c b/PGU/OLD/asm/max.c
new file mode 100644
index 0000000..5b4c37a
--- /dev/null
+++ b/PGU/OLD/asm/max.c
@@ -0,0 +1,27 @@
+int main(void)
+{
+
+ static int list[] = {10,20,30,40,5,50,60,70,80,90,0};
+ int i, ret;
+
+ ret = list[0];
+ i = 0;
+
+ /*
+ for (i = 0; list[i] != 0; i++) {
+ if (list[i] < ret)
+ ret = list[i];
+ }
+ */
+ while (1) {
+ i++;
+
+ if (list[i] == 0)
+ return ret;
+
+ if (ret > list[i])
+ ret = list[i];
+ }
+
+ return ret;
+}
diff --git a/PGU/OLD/asm/max.s b/PGU/OLD/asm/max.s
new file mode 100644
index 0000000..21f750a
--- /dev/null
+++ b/PGU/OLD/asm/max.s
@@ -0,0 +1,39 @@
+ .file "max.c"
+ .text
+ .globl main
+ .type main, @function
+main:
+.LFB0:
+ .cfi_startproc
+ movl $list.1406+8, %ecx
+ movl $20, %edx
+ movl $10, %eax
+.L2:
+ cmpl %edx, %eax
+ cmovg %edx, %eax
+ addl $4, %ecx
+ movl -4(%ecx), %edx
+ testl %edx, %edx
+ jne .L2
+ rep ret
+ .cfi_endproc
+.LFE0:
+ .size main, .-main
+ .section .rodata
+ .align 32
+ .type list.1406, @object
+ .size list.1406, 44
+list.1406:
+ .long 10
+ .long 20
+ .long 30
+ .long 40
+ .long 5
+ .long 50
+ .long 60
+ .long 70
+ .long 80
+ .long 90
+ .long 0
+ .ident "GCC: (GNU) 6.2.1 20160916 (Red Hat 6.2.1-2)"
+ .section .note.GNU-stack,"",@progbits
diff --git a/PGU/OLD/asm/maximum b/PGU/OLD/asm/maximum
new file mode 100644
index 0000000..4c7b855
--- /dev/null
+++ b/PGU/OLD/asm/maximum
Binary files differ
diff --git a/PGU/OLD/asm/maximum.s b/PGU/OLD/asm/maximum.s
new file mode 100644
index 0000000..cb6394c
--- /dev/null
+++ b/PGU/OLD/asm/maximum.s
@@ -0,0 +1,14 @@
+#%edi holds the current position
+#%ebx hold the current highest value
+#%eax hold the current element being examined
+
+.section.data data_items:
+.long 3, 4, 5, 65, 44, 36, 99, 6, 7, 8, 9, 0
+ data_end:.section.text.globl _start
+ _start:movl $ (data_items), %edi
+movl (%edi), %eax
+movl % eax, %ebx
+start_loop:cmpl $ (data_end), %edi
+je loop_exit
+addl $4, %edi
+movl (%edi), %eax cmpl % ebx, %eax jle start_loop movl % eax, %ebx jmp start_loop loop_exit:movl $1, %eax int $0x80
diff --git a/PGU/OLD/chapter3/exit b/PGU/OLD/chapter3/exit
new file mode 100644
index 0000000..a70d0fd
--- /dev/null
+++ b/PGU/OLD/chapter3/exit
Binary files differ
diff --git a/PGU/OLD/chapter3/exit.s b/PGU/OLD/chapter3/exit.s
new file mode 100644
index 0000000..632ebed
--- /dev/null
+++ b/PGU/OLD/chapter3/exit.s
@@ -0,0 +1,70 @@
+# A useless program, which the only thing this shit does is call exit syscall
+# The exit status code can be read using
+
+# `echo $?` on shell, which will show the exit status of the last program run.
+
+
+# %eax holds the system call number
+# %ebx holds the return status
+
+
+# Assembler directives (or pseudo-operations).
+#
+# Everything starting with a period, is an instruction to the assembler itself.
+# They are handled by the assembler program, not actually executed by the
+# computer.
+
+# .section command breaks the program down into sections.
+
+# .data section lists any memory storage which will be needed for data
+.section .data
+
+# .text section lists the program instructions
+.section .text
+
+# Instructs the assembler that _start is "important to remember".
+# _start is a symbol, which is going to be replaced by something else either
+# during assembly or linking
+
+# Symbols are generally used to mark locations of programs or data, so you can
+# refer to them by name instead of by location number
+
+# .globl means that the assembler should not discard this symbol after assembly,
+# because the linker will need it.
+
+# _start is a special symbol that always needs to be marked with .globl, because
+# it marks the location of the start of the program.
+
+# If the program is not marked this way, when the computer loads the program, it
+# won't know where to begin running the program.
+
+.globl _start
+
+# Defines the value of _start label. Label == a symbol followed by a colon.
+# Labels defines a symbol's value.
+
+# Labels tell the assembler to make the symbol's value be wherever the next
+# instruction or data element will be.
+
+_start:
+
+# different from the book, I'm using x86_64 instructions and its registers, so,
+# instead of using %eax and %ebx, I'm using %rax and %rbx directly. The movl
+# instruction needed to be changed to movq (move quad) to adapt to the 64-bit
+# registers
+# mov: (move) 16-bit
+# movl: (move long) 32-bit
+# movq: (move quad) 64-bit
+
+#ins $(val), (dest) == immediate mode
+movq $1, %rax # Move value 1 into %eax register
+ # %eax will hold the syscall number
+ # by the linux's calling convention
+
+movq $100, %rbx # Move value 0 into %ebx register
+ # %ebx will hold the exit() syscall
+ # argument.
+
+int $0x80 # Interrupt 0x80 will wake up the kernel
+ # execute the syscall loaded into %eax
+
diff --git a/PGU/OLD/chapter3/max.s b/PGU/OLD/chapter3/max.s
new file mode 100644
index 0000000..6ebc906
--- /dev/null
+++ b/PGU/OLD/chapter3/max.s
@@ -0,0 +1,42 @@
+# Given a list of X numbers, find the maximum number of the list and use it as
+# the argument of exit() syscall
+
+# %rbx holds the maximum number through the whole scanning process
+# %rax holds the current element being examined
+# %rdi holds the currend position in the list
+# zero marks the end of the list
+
+# Data section, now containing some statically created data
+.section .data
+
+# Just a label to refer to the first item in the list
+data_items:
+ # "Type" of memory location to be reserved. In quotes because it just
+ # says how many bytes should be reserved to each item, not the 'type'
+ # itself
+ # Reserves 10 '8byte' (quad) slots consecutive in memory,
+ .quad 3,10,9,230,66,77,23,66,12,69,0
+
+.section .text
+
+.globl _start
+
+_start:
+ movq $0, %rdi
+ movq data_items(, %rdi,8), %rax
+ movq %rax, %rbx
+
+ start_loop:
+ cmpq $0, %rax
+ je loop_exit
+ incq %rdi
+ movq data_items(,%rdi,8), %rax
+ cmpq %rbx, %rax
+ jle start_loop
+ movq %rax, %rbx
+ jmp start_loop
+
+
+ loop_exit:
+ movq $1, %rax
+ int $0x80
diff --git a/PGU/OLD/chapter3/min.s b/PGU/OLD/chapter3/min.s
new file mode 100644
index 0000000..9179be7
--- /dev/null
+++ b/PGU/OLD/chapter3/min.s
@@ -0,0 +1,52 @@
+# This code has been originally copied from max.s
+
+# It has been modified to:
+# - Find the smallest value, instead of the largest
+# - Use Start/End addresses to delimit the boundaries of the number list
+#
+# %rax - holds the current element being examined
+# %rbx - Holds the smallest number
+
+.section .data
+
+# This version has 2 labels, one to point to the start of the list, and another
+# to point to the address right after it, so we can use it to search the list
+# boundary.
+
+data_items:
+ .quad 234,10,9,230,66,77,23,66,101,69,100
+data_end:
+
+.section .text
+
+.globl _start
+
+_start:
+
+# Using immediate mode with a label, will give you the ADDRESS of the
+# instruction/data it points to. Once the label itself contains an ADDRESS, the
+# immediate mode will give you the ADDRESS itself.
+
+# Using direct mode with a label, will give you the DATA into the address the
+# label points to. Once the label itself contains an address, the direct mode,
+# as expected will give you the DATA into the address pointed by the label.
+ movq $data_items, %rax
+ cmpq $data_end, %rax # We need this check here in case
+ je exit_loop_empty # the items list is empty
+ movq (%rax), %rbx
+
+ loop_start:
+ addq $8, %rax # We are using QuadWords, so 8 bytes
+ cmpq $data_end, %rax
+ je exit_loop
+
+ cmpq (%rax), %rbx
+ jle loop_start
+ movq (%rax), %rbx
+ jmp loop_start
+
+ exit_loop_empty:
+ movq $255, %rbx
+ exit_loop:
+ movq $1, %rax
+ int $0x80
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