diff options
| author | mithe24 <mithe24@student.sdu.dk> | 2025-09-29 16:53:18 +0200 |
|---|---|---|
| committer | mithe24 <mithe24@student.sdu.dk> | 2025-10-29 13:49:57 +0100 |
| commit | 703af39239b9dbb8a4159cc39fc483e4cc8df1b6 (patch) | |
| tree | 8d331b974bf430ee3a9df91fc0e5e04078fdd7f5 | |
| parent | c6d80b48f91d8eaadf0d87bdd0bba6a4c5f1324d (diff) | |
| download | sorter-703af39239b9dbb8a4159cc39fc483e4cc8df1b6.tar.gz sorter-703af39239b9dbb8a4159cc39fc483e4cc8df1b6.zip | |
chore: Added provided code snippets
| -rw-r--r-- | snippets/allocate.s | 20 | ||||
| -rw-r--r-- | snippets/fileHandling.s | 16 | ||||
| -rw-r--r-- | snippets/parsing.s | 76 |
3 files changed, 112 insertions, 0 deletions
diff --git a/snippets/allocate.s b/snippets/allocate.s new file mode 100644 index 0000000..ef80957 --- /dev/null +++ b/snippets/allocate.s @@ -0,0 +1,20 @@ +# void *allocate(int n) +# +# A naive memory allocator that simply retrieves some new space from the OS. +# It is not possible to deallocate the memory again. +.globl allocate +.type allocate, @function +allocate: + push %rdi + # 1. Find the current end of the data segment. + movq $12, %rax # brk + xorq %rdi, %rdi # 0 means we retrieve the current end. + syscall + # 2. Add the amount of memory we want to allocate. + pop %rdi # the argument + push %rax # current end, which is where the allocated memory will start + addq %rax, %rdi # compute the new end + movq $12, %rax # brk + syscall + pop %rax # the old end, which is the address of our allocated memory + ret diff --git a/snippets/fileHandling.s b/snippets/fileHandling.s new file mode 100644 index 0000000..17a9428 --- /dev/null +++ b/snippets/fileHandling.s @@ -0,0 +1,16 @@ +# int getFileSize(int fd) +# +# Returns the size (in bytes) of the file indicated by the file descriptor. +.section .data +.Lstat: .space 144 # size of the fstat struct +.section .text +.globl getFileSize +.type getFileSize, @function +getFileSize: + movq $5, %rax # fstat + # rdi already contains the fd + movq $.Lstat, %rsi # buffer to write fstat data into + syscall + movq $.Lstat, %rax + movq 48(%rax), %rax # position of size in the struct + ret diff --git a/snippets/parsing.s b/snippets/parsing.s new file mode 100644 index 0000000..e039be6 --- /dev/null +++ b/snippets/parsing.s @@ -0,0 +1,76 @@ +# int getLineCount(const char *data, int size) +# +# Returns the number of '\n' characters in the memory pointed to. +# 'data': the address of the first character to look at. +# 'size': the length of the memory area to scan through. +.globl getLineCount +.type getLinecount, @function +getLineCount: + # rdi: 'data' + # rsi: 'size' + addq %rdi, %rsi # make rsi the past-the-end pointer + xorq %rax, %rax # count = 0 +.LgetLineCount_loop: + cmpq %rdi, %rsi + je .LgetLineCount_end # if rdi == rsi: we are done + movb (%rdi), %dl # load the next byte + addq $1, %rdi + cmpb $0xA, %dl # is it a newline char? + jne .LgetLineCount_loop # if not, continue in the buffer + addq $1, %rax # completed a number + jmp .LgetLineCount_loop +.LgetLineCount_end: + ret + + +# void parseData(const char *data, int size, int *result) +# +# Converts the ASCII representation of the coordinates into pairs of numbers. +# 'data': the address of the first character in the ASCII representation. +# 'size': the length of the ASCII representation. +# 'result': the address of a piece of memory big enough to hold the +# coordinates. If there are n coordinates in the input, the 'result' +# memory will be an array of 2n 8-byte integers, with alternating x and y +# coordinates. +# +# Note, this functions only expects unsigned ints in the input and does not +# perform any validity checks at all. +.globl parseData +.type parseData, @function +parseData: + addq %rdi, %rsi # make rsi the past-the-end pointer + push %rsi # and store it as the top element on the stack +.LparseData_coordinateLoop: + cmpq (%rsp), %rdi + je .LparseData_coordinateLoop_end + movq $9, %rsi # '\t' + call parseNumber # increases rdi to point past-the-end of the number + movq %rax, (%rdx) # store the number + addq $8, %rdx # point to the next place for a number + movq $10, %rsi # '\n' + call parseNumber # increases rdi to point past-the-end of the number + movq %rax, (%rdx) # store the number + addq $8, %rdx # point to the next place for a number + jmp .LparseData_coordinateLoop +.LparseData_coordinateLoop_end: + addq $8, %rsp + ret + +# int parseNumber(const char *&data, const char *end) +parseNumber: + xorq %rax, %rax # result +.LparseNumber_loop: + xorq %r10, %r10 # the next digit + movb (%rdi), %r10b # read character + addq $1, %rdi # ++data + cmpq %rsi, %r10 # done with this number? + je .LparseNumber_loop_end + # here we assume that the character is actually a digit + # add this digit to the current number + subq $48, %r10 # convert the ASCII code to the digit it represents + imul $10, %rax # 'make room' for the new digit + addq %r10, %rax # and add the new digit + jmp .LparseNumber_loop +.LparseNumber_loop_end: + # we now have a number in rax + ret |