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 | |
| parent | 869e68986aa8f69af6e7842260a68d1e5c6f796f (diff) | |
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'PGU/OLD')
| -rw-r--r-- | PGU/OLD/asm/exit.s | 17 | ||||
| -rw-r--r-- | PGU/OLD/asm/max.c | 27 | ||||
| -rw-r--r-- | PGU/OLD/asm/max.s | 39 | ||||
| -rw-r--r-- | PGU/OLD/asm/maximum | bin | 0 -> 1120 bytes | |||
| -rw-r--r-- | PGU/OLD/asm/maximum.s | 14 | ||||
| -rw-r--r-- | PGU/OLD/chapter3/exit | bin | 0 -> 704 bytes | |||
| -rw-r--r-- | PGU/OLD/chapter3/exit.s | 70 | ||||
| -rw-r--r-- | PGU/OLD/chapter3/max.s | 42 | ||||
| -rw-r--r-- | PGU/OLD/chapter3/min.s | 52 | ||||
| -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 |
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 Binary files differnew file mode 100644 index 0000000..4c7b855 --- /dev/null +++ b/PGU/OLD/asm/maximum 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 Binary files differnew file mode 100644 index 0000000..a70d0fd --- /dev/null +++ b/PGU/OLD/chapter3/exit 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 |
