From 2bd8c009b58d4ec79c3c82e2c998f517536baf0e Mon Sep 17 00:00:00 2001 From: unlockable Date: Thu, 2 May 2024 21:49:44 +0800 Subject: [PATCH 01/16] TA release HW1 --- 1/README.txt | 7 ++ 1/example/example.in | Bin 0 -> 20 bytes 1/example/example.out | Bin 0 -> 16 bytes 1/example/example_0.asm | 58 ++++++++++++++ 1/example/example_1.asm | 12 +++ 1/example/example_2.asm | 50 ++++++++++++ 1/example/example_3.asm | 35 +++++++++ 1/exp1/a.in | Bin 0 -> 8 bytes 1/exp1/exp1_1.cpp | 18 +++++ 1/exp1/exp1_2.cpp | 12 +++ 1/exp1/exp1_3.cpp | 15 ++++ 1/exp1/exp1_4.cpp | 18 +++++ 1/exp2/a.in | Bin 0 -> 84 bytes 1/exp2/binary_insert_sort.cpp | 58 ++++++++++++++ 1/exp2/insert_sort.cpp | 59 ++++++++++++++ 1/exp2/merge_sort.cpp | 121 +++++++++++++++++++++++++++++ 1/exp2/merge_sort_runnable.cpp | 135 +++++++++++++++++++++++++++++++++ 17 files changed, 598 insertions(+) create mode 100644 1/README.txt create mode 100644 1/example/example.in create mode 100644 1/example/example.out create mode 100644 1/example/example_0.asm create mode 100644 1/example/example_1.asm create mode 100644 1/example/example_2.asm create mode 100644 1/example/example_3.asm create mode 100644 1/exp1/a.in create mode 100644 1/exp1/exp1_1.cpp create mode 100644 1/exp1/exp1_2.cpp create mode 100644 1/exp1/exp1_3.cpp create mode 100644 1/exp1/exp1_4.cpp create mode 100644 1/exp2/a.in create mode 100644 1/exp2/binary_insert_sort.cpp create mode 100644 1/exp2/insert_sort.cpp create mode 100644 1/exp2/merge_sort.cpp create mode 100644 1/exp2/merge_sort_runnable.cpp diff --git a/1/README.txt b/1/README.txt new file mode 100644 index 0000000..b1cba71 --- /dev/null +++ b/1/README.txt @@ -0,0 +1,7 @@ +汇编大作业说明文档.docx 本次作业的具体内容说明 +汇编实验指导.pdf 为MIPS重点内容复习及大作业解释 +example/ “MARS环境安装与基础使用方法”部分参考代码 +exp1/ 作业“第一部分:基础练习”参考代码和样例数据 +exp2/ 作业“第二部分:实战应用”参考代码和样例数据 +attachment/ 实验用附件 +reference/ 参考文献 \ No newline at end of file diff --git a/1/example/example.in b/1/example/example.in new file mode 100644 index 0000000000000000000000000000000000000000..dd1dcccb192cac0a04f1e4eaa4818b1894d5427f GIT binary patch literal 20 YcmZQ!U|?uqWMC*~W? literal 0 HcmV?d00001 diff --git a/1/example/example_0.asm b/1/example/example_0.asm new file mode 100644 index 0000000..cd46aaf --- /dev/null +++ b/1/example/example_0.asm @@ -0,0 +1,58 @@ +.data +in_buff: .space 512 +out_buff: .space 512 +input_file: .asciiz "example.in" +output_file: .asciiz "example.out" +comma: .asciiz ", " +.text +la $a0, input_file #input_file һַ +li $a1, 0 #flag 0Ϊȡ 1Ϊд +li $a2, 0 #mode is ignored Ϊ0Ϳ +li $v0, 13 #13 Ϊļ syscall +syscall # 򿪳ɹ ļص$v0 + move $a0,$v0 # ļ뵽 $a0 + la $a1, in_buff #in_buff Ϊݴ + li $a2, 512 #ȡ512byte + li $v0, 14 #14 Ϊȡļ syscall + syscall + li $v0 16 #16 Ϊرļ syscall + syscall + +#ַʼѭֵΪN +la $s0, in_buff +la $s1, out_buff +lw $s2, 0($s0) +li $t0, 0 + +#ַ4 ѭ1 +for: addi $s0, $s0, 4 +addi $t0, $t0, 1 +lw $t1, 0($s0) +sw $t1, 0($s1) +addi $s1, $s1, 4 +#ӡ +move $a0, $t1 +li $v0, 1 +syscall +#ӡ +la $a0, comma +li $v0, 4 +syscall +bne $t0 $s2 for + +la $a0, output_file #output_file һַ +li $a1, 1 #flag 0Ϊȡ 1Ϊд +li $a2, 0 #mode is ignored Ϊ0Ϳ +li $v0, 13 #13 Ϊļ syscall +syscall # 򿪳ɹ ļص$v0 + +move $a0,$v0 # ļ뵽 $a0 +la $a1, out_buff #in_buff Ϊݴ +sll $s2 $s2 2 +move $a2, $s2 #д512byte +li $v0, 15 #15 Ϊдļ syscall +syscall +#ʱ$a0 еļû +#ֱӵ syscall 16 ر +li $v0 16 #16 Ϊرļ syscall +syscall diff --git a/1/example/example_1.asm b/1/example/example_1.asm new file mode 100644 index 0000000..b889dc6 --- /dev/null +++ b/1/example/example_1.asm @@ -0,0 +1,12 @@ +.data + .a + string: .asciiz "Hello World!\n" + +.text +main: + la $a0 string #载入字符串地址 + li $v0 4 #4代表打印字符串 + syscall #执行系统调用 + + li $v0 17 #17代表exit + syscall #执行系统调用 diff --git a/1/example/example_2.asm b/1/example/example_2.asm new file mode 100644 index 0000000..ae168c6 --- /dev/null +++ b/1/example/example_2.asm @@ -0,0 +1,50 @@ + .data + stringz: .asciiz "Hello World!\n" + string: .ascii "Hello World!\n" + #让array对齐到4byte边界 + .align 4 #没有这句话可能会出错 + array: .space 512 + #以下常数数组会自动对齐到对应边界 + barray: .byte 1,2,3,4 + harray: .half 1,2,3,4 + warray: .word 1,2,3,4 + + +.text +main: + la $a0 stringz #载入字符串地址 + li $v0 4 #4代表打印字符串 + syscall #执行系统调用 + + la $a0 string #载入字符串地址 + li $v0 4 #4代表打印字符串 + syscall #执行系统调用 + + la $t0 barray #载入byte数组地址 + lb $a0 0($t0) #读取barray[0] + li $v0 1 #1代表打印一个整数 + syscall #打印array[0]的数据 + lb $a0 1($t0) #读取barray[1] + li $v0 1 #1代表打印一个整数 + syscall #打印array[0]的数据 + lb $a0 2($t0) #读取barray[2] + li $v0 1 #1代表打印一个整数 + syscall #打印array[0]的数据 + lb $a0 3($t0) #读取barray[3] + li $v0 1 #1代表打印一个整数 + syscall #打印array[0]的数据 + + li $a0 10 #10代表换行符'\n' + li $v0 11 #11代表打印字符 + syscall #换个行 + + la $t0 array #载入array的地址 + li $t1 123 + sw $t1 0($t0) #在array[0]的位置存入123 + lw $a0 0($t0) #读取array[0]的数据 + li $v0 1 #1代表打印一个整数 + syscall #打印array[0]的数据 + + + li $v0 17 #17代表exit + syscall #执行系统调用 diff --git a/1/example/example_3.asm b/1/example/example_3.asm new file mode 100644 index 0000000..1aa3873 --- /dev/null +++ b/1/example/example_3.asm @@ -0,0 +1,35 @@ +.text +main: + li $v0 5 #5代表读入一个整数 + syscall #ִ执行系统调用 + move $a0 $v0 #将读入的整数作为第一个参数 + li $v0 5 #5代表读入一个整数 + syscall #ִ执行系统调用 + move $a1 $v0 #将读入的整数作为第二个参数 + + jal product #跳转到子过程product + move $a0 $v0 #将返回值赋值给$a0 + li $v0 1 #1代表打印一个整数 + syscall #ִ执行系统调用 + + li $v0 17 #17代表exit + syscall #ִ执行系统调用 + +product: + move $t0 $a0 #将第一个参数赋值给t0作为累加值 + move $t1 $a1 #将第二个参数赋值给t1作为计数器 + move $t2 $zero#结果清零 + addi $sp $sp -16 #移动栈指针到栈顶 + sw $t0 12($sp) #存入本地变量t0 + sw $t1 8($sp) #存入本地变量t1 + sw $t2 4($sp) #存入本地变量t2 + sw $ra 0($sp) #存入过程返回地址 + loop: add $t2 $t2 $t0 #结果累计t0 + sw $t2 4($sp) #存入本地变量t2 + addi $t1 $t1 -1 #计数器减一 + sw $t1 8($sp) #存入本地变量t2 + bnez $t1 loop #如果计数器不为0循环继续 + move $v0 $t2 #将结果赋给返回值 + lw $ra 0($sp) #出栈过程返回地址 + jr $ra #跳转回上一级过程 + diff --git a/1/exp1/a.in b/1/exp1/a.in new file mode 100644 index 0000000000000000000000000000000000000000..6f363cafee10987d6044d3f321d5521858979b7c GIT binary patch literal 8 NcmZQ%U|`?^VgLX*01N;C literal 0 HcmV?d00001 diff --git a/1/exp1/exp1_1.cpp b/1/exp1/exp1_1.cpp new file mode 100644 index 0000000..8e3bf5c --- /dev/null +++ b/1/exp1/exp1_1.cpp @@ -0,0 +1,18 @@ +#include "stdio.h" + +int main() { + FILE *infile ,*outfile; + int i; + int *buffer; + buffer = new int[2]; + infile = fopen("a.in", "rb"); + fread(buffer, 4, 2, infile); + fclose(infile); + outfile = fopen("a.out", "wb"); + fwrite(buffer, 4, 2, outfile); + fclose(outfile); + scanf("%d", &i); + i = i + 10; + printf("%d", i); + return 0; +} diff --git a/1/exp1/exp1_2.cpp b/1/exp1/exp1_2.cpp new file mode 100644 index 0000000..8fa5a82 --- /dev/null +++ b/1/exp1/exp1_2.cpp @@ -0,0 +1,12 @@ +#include "stdio.h" + +int main() { + int i, j, temp; + scanf("%d", &i); + scanf("%d", &j); + i = -i; + if(j < 0) j = -j; + for(temp = 0; temp < j; ++temp) i += 1; + printf("%d",i); + return 0; +} diff --git a/1/exp1/exp1_3.cpp b/1/exp1/exp1_3.cpp new file mode 100644 index 0000000..c22c25a --- /dev/null +++ b/1/exp1/exp1_3.cpp @@ -0,0 +1,15 @@ +#include "stdio.h" + +int main() { + int *a, n, i, t; + scanf("%d", &n); + a = new int [n]; + for(i = 0; i < n; i++) scanf("%d",&a[i]); + for(i = 0; i < n / 2; i++) { + t = a[i] + 1; + a[i] = a[n - i - 1] + 1; + a[n - i - 1] = t; + } + for(i = 0;i < n; i++) printf("%d", a[i]); + return 0; +} diff --git a/1/exp1/exp1_4.cpp b/1/exp1/exp1_4.cpp new file mode 100644 index 0000000..50427eb --- /dev/null +++ b/1/exp1/exp1_4.cpp @@ -0,0 +1,18 @@ +#include "stdio.h" + +int Hanoi(int n) +{ + if (n == 1) { // 基准情形 + return 1; + } else { // 递归情形 + return 2 * Hanoi(n - 1) + 1; + } +} + +int main() +{ + int n; + scanf("%d", &n); + printf("%d", Hanoi(n)); + return 0; +} \ No newline at end of file diff --git a/1/exp2/a.in b/1/exp2/a.in new file mode 100644 index 0000000000000000000000000000000000000000..2fdfd438c02588850a24e9b190a14c8b93e19e8b GIT binary patch literal 84 zcmWN}Ar687006)X7B&+j@CO5t=_qUjEjIiR8M6F right) + return left; // 递归边界,此处不统计比较次数 + int mid = (left + right) >> 1; + compare_count++; // 统计比较次数 + if (v[mid] > v[n]) + return binary_search(v, left, mid - 1, n); + else + return binary_search(v, mid + 1, right, n); +} + +// 将新的元素插入到指定位置,并将后续元素后移 +void insert(int *v, int k, int n) +{ + int i; + int tmp = v[n]; + for (i = n - 1; i >= k; i--) + { + v[i + 1] = v[i]; + } + v[k] = tmp; +} + +void binary_insertion_sort(int v[], int n) +{ + int i; + for (i = 1; i < n; i++) + { // 从第二个元素开始,依次插入到前面已经排好序的序列中 + int place = binary_search(v, 0, i - 1, i); + insert(v, place, i); + } +} + +int main() +{ + FILE *infile, *outfile; + int buffer[1001]; + infile = fopen("a.in", "rb"); + fread(buffer, 4, 1001, infile); + fclose(infile); + int N = buffer[0]; + binary_insertion_sort(&(buffer[1]), N); + buffer[0] = compare_count; + outfile = fopen("a.out", "wb"); + fwrite(buffer, 4, N + 1, outfile); + fclose(outfile); + return 0; +} diff --git a/1/exp2/insert_sort.cpp b/1/exp2/insert_sort.cpp new file mode 100644 index 0000000..0dc990c --- /dev/null +++ b/1/exp2/insert_sort.cpp @@ -0,0 +1,59 @@ +#include "stdio.h" +/* + 插入排序:将一个元素插入到一个已经排好序的序列中,使得序列依然有序。 +*/ + +// 统计比较次数 +int compare_count = 0; + +// 从后往前查找第一个比v[n]小的元素,其后一个位置即为插入位置 +int search(int v[], int n) +{ + int i; + int tmp = v[n]; + for (i = n - 1; i >= 0; i--) + { + compare_count++; // 统计比较次数 + if (v[i] <= tmp) + break; + } + return i + 1; +} + +// 将新的元素插入到指定位置,并将后续元素后移 +void insert(int *v, int k, int n) +{ + int i; + int tmp = v[n]; + for (i = n - 1; i >= k; i--) + { + v[i + 1] = v[i]; + } + v[k] = tmp; +} + +void insertion_sort(int v[], int n) +{ + int i; + for (i = 1; i < n; i++) + { // 从第二个元素开始,依次插入到前面已经排好序的序列中 + int place = search(v, i); + insert(v, place, i); + } +} + +int main() +{ + FILE *infile, *outfile; + int buffer[1001]; + infile = fopen("a.in", "rb"); + fread(buffer, 4, 1001, infile); + fclose(infile); + int N = buffer[0]; + insertion_sort(&(buffer[1]), N); + buffer[0] = compare_count; + outfile = fopen("a.out", "wb"); + fwrite(buffer, 4, N + 1, outfile); + fclose(outfile); + return 0; +} diff --git a/1/exp2/merge_sort.cpp b/1/exp2/merge_sort.cpp new file mode 100644 index 0000000..0ea9b88 --- /dev/null +++ b/1/exp2/merge_sort.cpp @@ -0,0 +1,121 @@ +#include "stdio.h" /* + +链表的归并排序的核心是将链表分成前后两段,分别排序后对两个有序链表归并,递归边界是当前链表长度为1。 +*/ + +int compare_count = 0; + +// 两个有序链表合并 , 将右链元素插入到左链中 。 +int *merge(int *l_head, int *r_head) +{ + // 这里构建一个虚拟头结点 , 方便在第一个元素前插入 。 + int *head = new int[2]; + head[1] = (int)l_head; + int *p_left = head; + int *p_right = r_head; + do + { + do + { // 寻找左链中的插入位置 + if (p_left[1] == (int)NULL) + break; + // count the number of comparisons + compare_count++; + if (((int *)p_left[1])[0] > p_right[0]) + break; + p_left = (int *)p_left[1]; + } while (1); + // 如果到达左链尾端 , 右链直接接上 + if (p_left[1] == (int)NULL) + { + p_left[1] = (int)p_right; + break; + } + int *p_right_temp = p_right; + do + { // 寻找右链待插入片段 + if (p_right_temp[1] == (int)NULL) + break; + // count the number of comparisons + compare_count++; + if (((int *)p_right_temp[1])[0] > ((int *)p_left[1])[0]) + break; + p_right_temp = (int *)p_right_temp[1]; + } while (1); + // 完成插入操作 + int *temp_right_pointer_next = (int *)p_right_temp[1]; + p_right_temp[1] = p_left[1]; + p_left[1] = (int)p_right; + p_left = p_right_temp; + p_right = temp_right_pointer_next; + if (p_right == NULL) + break; + } while (1); + int rv = head[1]; + + delete head; + return (int *)rv; +} + +// 归并排序主函数 , 先找链表中点 , 再分别排序 , 最后归并 +int *msort(int *head) +{ + if (head[1] == (int)NULL) + return head; + int *stride_2_pointer = head; + int *stride_1_pointer = head; + do + { // 通过同时进行步长为 1 和步长为 2 的跳转找中点 + if (stride_2_pointer[1] == (int)NULL) + break; + stride_2_pointer = (int *)stride_2_pointer[1]; + if (stride_2_pointer[1] == (int)NULL) + break; + stride_2_pointer = (int *)stride_2_pointer[1]; + stride_1_pointer = (int *)stride_1_pointer[1]; + } while (1); + // 拆成两个链表分别排序 , 再归并 。 + stride_2_pointer = (int *)stride_1_pointer[1]; + stride_1_pointer[1] = (int)NULL; + int *l_head = msort(head); + int *r_head = msort(stride_2_pointer); + return merge(l_head, r_head); +} + +int main() +{ + FILE *infile, *outfile; + int buffer[1001]; + infile = fopen("a.in", "rb"); + fread(buffer, 4, 1001, infile); + fclose(infile); + int N = buffer[0]; + // create a linked list + int *head = new int[2]; + head[1] = (int)NULL; + int *pointer = head; + for (int idx = 1; idx <= N; idx++) + { + pointer[1] = (int)new int[2]; + pointer = (int *)pointer[1]; + pointer[0] = buffer[idx]; + pointer[1] = (int)NULL; + } + // sort + head[1] = (int)msort((int *)head[1]); + pointer = head; + outfile = fopen("a.out", "wb"); + // 输出比较次数 + fwrite(&compare_count, 4, 1, outfile); + // wirte the sorted list to file + do + { + pointer = (int *)pointer[1]; + if (pointer == NULL) + break; + fwrite(pointer, 4, 1, outfile); + } while (1); + fclose(outfile); + // 本文件用于翻译,没有释放链表内存的操作 + return 0; +} diff --git a/1/exp2/merge_sort_runnable.cpp b/1/exp2/merge_sort_runnable.cpp new file mode 100644 index 0000000..b1521f7 --- /dev/null +++ b/1/exp2/merge_sort_runnable.cpp @@ -0,0 +1,135 @@ +#include "stdio.h" /* + +链表的归并排序的核心是将链表分成前后两段,分别排序后对两个有序链表归并,递归边界是当前链表长度为1。 + +!!!注意:此代码为可运行版本,目的是让大家检验自己的实验结果是否正确 +!!!其中的链表节点是通过结构体实现的,实际汇编的实现中指针也是32位整数,请参考另一个版本的代码(merge_sort.cpp) + +*/ + +// 统计待排序数据的比较次数 +int compare_count = 0; + +// 链表节点, 结构体实现 +struct Node +{ + int value; + Node *next; +}; + +// 两个有序链表合并,将右链元素插入到左链中 。 +Node *merge(Node *l_head, Node *r_head) +{ + // 这里构建一个虚拟头结点,方便在第一个元素前插入。 + Node *head = new Node; + head->next = l_head; + Node *p_left = head; + Node *p_right = r_head; + do + { + do + { // 寻找左链中的插入位置 + if (p_left->next == (int)NULL) + break; + compare_count++; // 统计比较次数 + if ((p_left->next)->value > p_right->value) + break; + p_left = p_left->next; + } while (1); + // 如果到达左链尾端,右链直接接上 + if (p_left->next == NULL) + { + p_left->next = p_right; + break; + } + Node *p_right_temp = p_right; + do + { // 寻找右链待插入片段 + if (p_right_temp->next == NULL) + break; + compare_count++; // 统计比较次数 + if ((p_right_temp->next)->value > (p_left->next)->value) + break; + p_right_temp = p_right_temp->next; + } while (1); + // 完成插入操作 + Node *temp_right_pointer_next = p_right_temp->next; + p_right_temp->next = p_left->next; + p_left->next = p_right; + p_left = p_right_temp; + p_right = temp_right_pointer_next; + if (p_right == NULL) + break; + } while (1); + Node *rv = head->next; + delete head; + return rv; +} + +// 归并排序主函数,先找链表中点,再分别排序,最后归并 +Node *msort(Node *head) +{ + if (head->next == NULL) + return head; + Node *stride_2_pointer = head; + Node *stride_1_pointer = head; + do + { // 通过同时进行步长为 1 和步长为 2 的跳转找中点 + if (stride_2_pointer->next == NULL) + break; + stride_2_pointer = stride_2_pointer->next; + if (stride_2_pointer->next == NULL) + break; + stride_2_pointer = stride_2_pointer->next; + stride_1_pointer = stride_1_pointer->next; + } while (1); + // 拆成两个链表分别排序 , 再归并 。 + stride_2_pointer = stride_1_pointer->next; + stride_1_pointer->next = NULL; + Node *l_head = msort(head); + Node *r_head = msort(stride_2_pointer); + return merge(l_head, r_head); +} + +int main() +{ + FILE *infile, *outfile; + int buffer[1001]; + infile = fopen("a.in", "rb"); + fread(buffer, 4, 1001, infile); + fclose(infile); + int N = buffer[0]; + Node *head = new Node; + head->next = NULL; + Node *pointer = head; + for (int idx = 1; idx <= N; idx++) + { + pointer->next = new Node; + pointer = pointer->next; + pointer->value = buffer[idx]; + pointer->next = NULL; + } + // 排序 + head->next = msort(head->next); + // 输出到文件 + pointer = head; + outfile = fopen("a.out", "wb"); + // 输出比较次数 + fwrite(&compare_count, 4, 1, outfile); + do + { + pointer = pointer->next; + if (pointer == NULL) + break; + fwrite(&(pointer->value), 4, 1, outfile); + } while (1); + fclose(outfile); + // 释放链表内存 + while (head != NULL) + { + Node *temp = head; + head = head->next; + delete temp; + } + return 0; +} From 9ab2fe967dceab9b8015e26b42a00bfde8432846 Mon Sep 17 00:00:00 2001 From: unlockable Date: Thu, 2 May 2024 21:54:26 +0800 Subject: [PATCH 02/16] 1.1 --- 1/homework/exp1/a.in | Bin 0 -> 8 bytes 1/homework/exp1/a.out | Bin 0 -> 8 bytes 1/homework/exp1/exp1_1.asm | 41 +++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 1/homework/exp1/a.in create mode 100644 1/homework/exp1/a.out create mode 100644 1/homework/exp1/exp1_1.asm diff --git a/1/homework/exp1/a.in b/1/homework/exp1/a.in new file mode 100644 index 0000000000000000000000000000000000000000..6f363cafee10987d6044d3f321d5521858979b7c GIT binary patch literal 8 NcmZQ%U|`?^VgLX*01N;C literal 0 HcmV?d00001 diff --git a/1/homework/exp1/a.out b/1/homework/exp1/a.out new file mode 100644 index 0000000000000000000000000000000000000000..6f363cafee10987d6044d3f321d5521858979b7c GIT binary patch literal 8 NcmZQ%U|`?^VgLX*01N;C literal 0 HcmV?d00001 diff --git a/1/homework/exp1/exp1_1.asm b/1/homework/exp1/exp1_1.asm new file mode 100644 index 0000000..4073168 --- /dev/null +++ b/1/homework/exp1/exp1_1.asm @@ -0,0 +1,41 @@ +.data +file_buff: .space 8 # A space of 2 bytes +input_file_name: .asciiz "a.in" +.align 2 +output_file_name: .asciiz "a.out" +.align 2 +.text + +la $a0, input_file_name +li $a1, 0 # set mode as read +li $a2, 0 # meaning nothing, really +li $v0, 13 # open file +syscall #now $v0 is the file handler + +move $a0, $v0 #move file handler to a0 as first syscall arg +la $a1, file_buff +li $a2, 8 # read in 8 bytes +li $v0, 14 +syscall +li $v0, 16 +syscall # close file + +la $a0, output_file_name +li $a1, 1 # set mode as write +li $a2, 0 # meaning nothing, really +li $v0, 13 # open file +syscall + +move $a0, $v0 +la $a1, file_buff +li $a2, 8 # write 8 bytes +li $v0, 15 # write file +syscall +li $v0, 16 +syscall + +li $v0 5 # read integer +syscall +addi $a0, $v0, 10 # a0 = v0 + 10 +li $v0 1 # print integer +syscall From b0373f27a18adab5e9a91b232e5690c38a0bff3d Mon Sep 17 00:00:00 2001 From: unlockable Date: Thu, 2 May 2024 22:26:27 +0800 Subject: [PATCH 03/16] Meet the requirements of align --- 1/homework/exp1/exp1_1.asm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/1/homework/exp1/exp1_1.asm b/1/homework/exp1/exp1_1.asm index 4073168..cf589eb 100644 --- a/1/homework/exp1/exp1_1.asm +++ b/1/homework/exp1/exp1_1.asm @@ -1,9 +1,10 @@ .data file_buff: .space 8 # A space of 2 bytes +.align 3 input_file_name: .asciiz "a.in" -.align 2 +.align 3 output_file_name: .asciiz "a.out" -.align 2 +.align 3 .text la $a0, input_file_name From a6b75962621474f29db3215087430a1b4c7ec7a4 Mon Sep 17 00:00:00 2001 From: unlockable Date: Thu, 2 May 2024 22:29:09 +0800 Subject: [PATCH 04/16] 1.2 --- 1/homework/exp1/exp1_2.asm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 1/homework/exp1/exp1_2.asm diff --git a/1/homework/exp1/exp1_2.asm b/1/homework/exp1/exp1_2.asm new file mode 100644 index 0000000..a07ab41 --- /dev/null +++ b/1/homework/exp1/exp1_2.asm @@ -0,0 +1,26 @@ +.data +.text +li $v0, 5 # read in i +syscall +move $s1, $v0 # use s1 to store i + +li $v0, 5 # read in j +syscall +move $s2, $v0 # use s2 to store j + +sub $s1, $zero, $s1 # i = -i + +bgez $s2, no_neg_j # if >= 0, then no neg +sub $s2, $zero, $s2 # j = -j + +no_neg_j: move $s0, $zero # use s0 as temp, temp = 0 +count_up_j: bge $s0, $s2, done_count_up # if temp >= j, stop iteration +addi $s1, $s1, 1 # i = i + 1 +addi $s0, $s0, 1 # ++temp +j count_up_j + +done_count_up: move $a0, $s1 +li $v0 1 +syscall + +move $v0, $s1 # set return value \ No newline at end of file From 4e1a5c0d6b29a9420e0fb17e14416f086c2b9311 Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 00:04:23 +0800 Subject: [PATCH 05/16] 1.3 --- 1/homework/exp1/exp1_3.asm | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 1/homework/exp1/exp1_3.asm diff --git a/1/homework/exp1/exp1_3.asm b/1/homework/exp1/exp1_3.asm new file mode 100644 index 0000000..3fdcbb9 --- /dev/null +++ b/1/homework/exp1/exp1_3.asm @@ -0,0 +1,60 @@ +.data +.text +li $v0 5 # read in num +syscall + +move $s0, $v0 # $s0 is n +move $a0, $v0 +li $v0, 9 # malloc +syscall +move $s1, $v0 # $s1 = a + +move $t0, $zero # a0 = 0 + +move $t0, $zero # i = 0 +move $t1, $s1 #t1 = a +read_in_num: bge $t0, $s0, done_read_in_num # i >= n, break +li $v0, 5 # read in num +syscall + +sw $v0, 0($t1) # a[i] = v0 +addi $t0, $t0, 1 # i++ +addi $t1, $t1, 4 # t1 += 4 +j read_in_num + +done_read_in_num: srl $s2, $s0, 1 # s1 = n / 2 +move $t0, $zero # i = 0 +move $t1, $s1 + +subi $t2, $s0, 1 # t2 = n - 1 +sll $t2, $t2, 2 # t2 *= 4 +add $t2, $t2, $s1 +reverse: bge $t0, $s2, done_reverse # i >= n / 2, break +lw $t3, 0($t1) # t3 = a[i] +addi $t3, $t3, 1 # t3 += 1 + +lw $t4, 0($t2) # t4 = a[n - i - 1] +addi $t4, $t4, 1 # t4 += 1 + +sw $t4, 0($t1) +sw $t3, 0($t2) + +addi $t0, $t0, 1 +addi $t1, $t1, 4 +subi $t2, $t2, 4 +j reverse + +done_reverse: move $t0, $zero +move $t1, $s1 + +output: bge $t0, $s0 done_output +lw $a0, 0($t1) +li $v0 1 +syscall + +addi $t0, $t0, 1 +addi $t1, $t1, 4 +j output + +done_output: li $v0 17 +syscall \ No newline at end of file From 08130c331c0f60cc4923ee3b7d600d733f2415e6 Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 00:06:38 +0800 Subject: [PATCH 06/16] Better format --- 1/homework/exp1/exp1_3.asm | 62 +++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/1/homework/exp1/exp1_3.asm b/1/homework/exp1/exp1_3.asm index 3fdcbb9..3f05bcb 100644 --- a/1/homework/exp1/exp1_3.asm +++ b/1/homework/exp1/exp1_3.asm @@ -13,48 +13,54 @@ move $t0, $zero # a0 = 0 move $t0, $zero # i = 0 move $t1, $s1 #t1 = a -read_in_num: bge $t0, $s0, done_read_in_num # i >= n, break -li $v0, 5 # read in num -syscall +read_in_num: + bge $t0, $s0, done_read_in_num # i >= n, break + li $v0, 5 # read in num + syscall -sw $v0, 0($t1) # a[i] = v0 -addi $t0, $t0, 1 # i++ -addi $t1, $t1, 4 # t1 += 4 -j read_in_num + sw $v0, 0($t1) # a[i] = v0 + addi $t0, $t0, 1 # i++ + addi $t1, $t1, 4 # t1 += 4 + j read_in_num -done_read_in_num: srl $s2, $s0, 1 # s1 = n / 2 +done_read_in_num: +srl $s2, $s0, 1 # s1 = n / 2 move $t0, $zero # i = 0 move $t1, $s1 subi $t2, $s0, 1 # t2 = n - 1 sll $t2, $t2, 2 # t2 *= 4 add $t2, $t2, $s1 -reverse: bge $t0, $s2, done_reverse # i >= n / 2, break -lw $t3, 0($t1) # t3 = a[i] -addi $t3, $t3, 1 # t3 += 1 +reverse: + bge $t0, $s2, done_reverse # i >= n / 2, break + lw $t3, 0($t1) # t3 = a[i] + addi $t3, $t3, 1 # t3 += 1 -lw $t4, 0($t2) # t4 = a[n - i - 1] -addi $t4, $t4, 1 # t4 += 1 + lw $t4, 0($t2) # t4 = a[n - i - 1] + addi $t4, $t4, 1 # t4 += 1 -sw $t4, 0($t1) -sw $t3, 0($t2) + sw $t4, 0($t1) + sw $t3, 0($t2) -addi $t0, $t0, 1 -addi $t1, $t1, 4 -subi $t2, $t2, 4 -j reverse + addi $t0, $t0, 1 + addi $t1, $t1, 4 + subi $t2, $t2, 4 + j reverse -done_reverse: move $t0, $zero +done_reverse: +move $t0, $zero move $t1, $s1 -output: bge $t0, $s0 done_output -lw $a0, 0($t1) -li $v0 1 -syscall +output: + bge $t0, $s0 done_output + lw $a0, 0($t1) + li $v0 1 + syscall -addi $t0, $t0, 1 -addi $t1, $t1, 4 -j output + addi $t0, $t0, 1 + addi $t1, $t1, 4 + j output -done_output: li $v0 17 +done_output: +li $v0 17 syscall \ No newline at end of file From 3dac8a6d9451befeeb21ce01021b432dba98abce Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 15:05:14 +0800 Subject: [PATCH 07/16] 1.4 --- 1/homework/exp1/exp1_4.asm | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 1/homework/exp1/exp1_4.asm diff --git a/1/homework/exp1/exp1_4.asm b/1/homework/exp1/exp1_4.asm new file mode 100644 index 0000000..e2c91f6 --- /dev/null +++ b/1/homework/exp1/exp1_4.asm @@ -0,0 +1,35 @@ +.data + +.text +main: + li $v0, 5 # read in + syscall + move $s0, $v0 # s0 is the n + move $a0, $s0 # set the first call arg as n + jal hanoi # call proc + move $a0, $v0 # print out + li $v0, 1 + syscall + li $v0, 17 + syscall + +hanoi: + li $t0, 1 + ble $a0, $t0, hanoi_bottom # if n <= 1, return + j hanoi_recur +hanoi_bottom: + li $v0, 1 # return 1 + jr $ra +hanoi_recur: + subi $sp, $sp, 8 # move sp down by 2 word + sw $s0, 4($sp) # first word is the n in caller + sw $ra, 0($sp) # second word is the return addr of this callee + move $s0, $a0 + subi $a0, $s0, 1 + jal hanoi + sll $v0, $v0, 1 # hanoi(n - 1) * 2 + ori $v0, $v0, 1 # hanoi(n - 1) * 2 + 1 + lw $s0, 4($sp) # reverse s0 + lw $ra, 0($sp) # reverse ra + addi $sp, $sp, 8 + jr $ra From 6e37c539469cb065c9e6773b3fadbac4b1405e3e Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 18:14:00 +0800 Subject: [PATCH 08/16] 2.1 --- 1/homework/exp2/a.in | Bin 0 -> 84 bytes 1/homework/exp2/insert_sort.asm | 188 ++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 1/homework/exp2/a.in create mode 100644 1/homework/exp2/insert_sort.asm diff --git a/1/homework/exp2/a.in b/1/homework/exp2/a.in new file mode 100644 index 0000000000000000000000000000000000000000..2fdfd438c02588850a24e9b190a14c8b93e19e8b GIT binary patch literal 84 zcmWN}Ar687006)X7B&+j@CO5t=_qUjEjIiR8M6F= n, done loop + move $a0, $s1 + jal search + + move $a0, $v0 + move $a1, $s1 + jal insert + + addi $s1, $s1, 1 # i ++ + j item_loop +done_item_loop: + + lw $ra, 0($sp) + addi $sp, $sp, 8 + jr $ra + +search: # $a0: int n + subi $sp, $sp, 12 + sw $s0, 8($sp) + sw $s1, 4($sp) + sw $ra, 0($sp) + + la $s0, num_buff + sll $t0, $a0, 2 + add $s2, $s0, $t0 + lw $s2, 0($s2) # s2 = tmp = v[n] + + subi $s1, $a0, 1 # i = n - 1 +search_loop: + bltz $s1, done_search_loop # i < 0, done loop + jal add_compare_count + + sll $t0, $s1, 2 + add $t0, $s0, $t0 + lw $t0, 0($t0) # t0 = v[i] + ble $t0, $s2, done_search_loop # if v[i] <= tmp, break + + subi $s1, $s1, 1 # i-- + j search_loop + +done_search_loop: + addi $v0, $s1, 1 # return i + 1 + + lw $s0, 8($sp) + lw $s1, 4($sp) + lw $ra, 0($sp) + addi $sp, $sp, 12 + jr $ra +insert: # $a0: int k, $a1: int n + subi $sp, $sp, 12 + sw $s0, 8($sp) + sw $s1, 4($sp) + sw $ra, 0($sp) + + la $s0, num_buff # s0 = &v[0] + + sll $t0, $a1, 2 + add $s2, $s0, $t0 + lw $s2, 0($s2) # s2 = tmp = 'pivot' = v[n] + + subi $s1, $a1, 1 # s1 = i = n - 1 + +insert_loop: + blt $s1, $a0, done_insert_loop # i < k, done loop + sll $t0, $s1, 2 + add $t0, $s0, $t0 # t0 = &v[i] + lw $t1, 0($t0) + sw $t1, 4($t0) + + subi $s1, $s1, 1 # i-- + j insert_loop +done_insert_loop: + sll $t0, $a0, 2 + add $t0, $s0, $t0 + sw $s2, 0($t0) # t0 = &v[k] + + lw $s0, 8($sp) + lw $s1, 4($sp) + lw $ra, 0($sp) + addi $sp, $sp, 12 + jr $ra + + +add_compare_count: + la $t0, compare_count + lw $t1, 0($t0) + addi $t1, $t1, 1 + sw $t1, 0($t0) + jr $ra + +print_num_in_buff: + la $t0, num_N + la $t2, num_buff + lw $t0, 0($t0) + li $t1, 0 +print_loop: + bge $t1, $t0, done_print_loop + + sll $a0, $t1, 2 + add $a0, $t2, $a0 + lw $a0, 0($a0) + li $v0, 1 + syscall + + la $a0, space_string + li $v0, 4 + syscall + + addi $t1, $t1, 1 + j print_loop + +done_print_loop: + la $a0, newline_string + li $v0, 4 + syscall + jr $ra From 30ad2353e076ba89ece7322e3d5cb6c61ff48138 Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 18:14:27 +0800 Subject: [PATCH 09/16] Better format --- 1/homework/exp2/insert_sort.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1/homework/exp2/insert_sort.asm b/1/homework/exp2/insert_sort.asm index f879fdb..64522f7 100644 --- a/1/homework/exp2/insert_sort.asm +++ b/1/homework/exp2/insert_sort.asm @@ -108,7 +108,7 @@ search_loop: ble $t0, $s2, done_search_loop # if v[i] <= tmp, break subi $s1, $s1, 1 # i-- - j search_loop + j search_loop done_search_loop: addi $v0, $s1, 1 # return i + 1 From 64771f7a0c6830166ad9c84d4fa21a141073e585 Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 19:53:25 +0800 Subject: [PATCH 10/16] 2.2 --- 1/homework/exp2/binary_insert_sort.asm | 205 +++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 1/homework/exp2/binary_insert_sort.asm diff --git a/1/homework/exp2/binary_insert_sort.asm b/1/homework/exp2/binary_insert_sort.asm new file mode 100644 index 0000000..6f6949f --- /dev/null +++ b/1/homework/exp2/binary_insert_sort.asm @@ -0,0 +1,205 @@ +.data +compare_count: .word 0 +num_N: .word 0 +input_file_name: .asciiz "a.in" + .align 2 +output_file_name: .asciiz "a.out" + .align 2 +space_string: .asciiz " " + .align 2 +newline_string: .asciiz "\r\n" + .align 2 +num_buff: .space 4096 + .align 2 + +.text +main: + la $a0, input_file_name + li $a1, 0 + li $a2, 0 + li $v0, 13 + syscall + + move $a0, $v0 # start to read in N + la $a1, num_N + li $a2, 4 + li $v0, 14 + syscall + + la $t0, num_N # read N * 4 bytes into num_buff + lw $a2, 0($t0) # read in num_N + sll $a2, $a2, 2 # n * 4 is the bytes to read + + la $a1, num_buff + + li $v0, 14 + syscall # read in file + li $v0, 16 + syscall # close file + # jal print_num_in_buff + + jal insertion_sort + + # jal print_num_in_buff + + la $a0, output_file_name + li $a1, 1 + li $a2, 0 + li $v0, 13 + syscall + + move $a0, $v0 + la $a1, compare_count + li $a2, 4 + li $v0, 15 + syscall + + la $a1, num_buff + la $a2, num_N + lw $a2, 0($a2) + sll $a2, $a2, 2 + li $v0, 15 + syscall + + li $v0, 17 + syscall # exit + +insertion_sort: + subi $sp, $sp, 4 + sw $ra, 0($sp) + + la $t0, num_N + lw $s0, 0($t0) # n in s0 + + li $s1, 1 # i in s1 +item_loop: + bge $s1, $s0, done_item_loop # if i >= n, done loop + li $a0, 0 + subi $a1, $s1, 1 + move $a2, $s1 + jal binary_search + + move $a0, $v0 + move $a1, $s1 + jal insert + + addi $s1, $s1, 1 # i ++ + j item_loop +done_item_loop: + + lw $ra, 0($sp) + addi $sp, $sp, 8 + jr $ra + +binary_search: # a0: left, a1: right, a2: i + subi $sp, $sp, 20 + sw $s0, 16($sp) + sw $s1, 12($sp) + sw $s2, 8($sp) + sw $s3, 4($sp) + sw $ra, 0($sp) + + ble $a0, $a1, in_boundary_binary_search # left <= right, in normal position + move $v0, $a0 # now in boundary condition + j done_binary_search + +in_boundary_binary_search: + move $s0, $a0 # in normal situation + move $s1, $a1 + move $s2, $a2 + add $s3, $s0, $s1 # s3 = mid = (left + right) >> 1 + srl $s3, $s3, 1 + jal add_compare_count + + la $t0, num_buff + sll $t1, $s3, 2 + add $t1, $t1, $t0 + lw $t1, 0($t1) # t1 = v[mid] + sll $t2, $s2, 2 + add $t2, $t2, $t0 + lw $t2, 0($t2) # t2 = v[n] + ble $t1, $t2, binary_search_right # v[mid] <= v[n], jump to 'else' +binary_search_left: + subi $a1, $s3, 1 + jal binary_search + j done_binary_search +binary_search_right: + addi $a0, $s3, 1 + jal binary_search +done_binary_search: + lw $s0, 16($sp) + lw $s1, 12($sp) + lw $s2, 8($sp) + lw $s3, 4($sp) + lw $ra, 0($sp) + addi $sp, $sp, 20 + jr $ra + +insert: # $a0: int k, $a1: int n + subi $sp, $sp, 12 + sw $s0, 8($sp) + sw $s1, 4($sp) + sw $ra, 0($sp) + + la $s0, num_buff # s0 = &v[0] + + sll $t0, $a1, 2 + add $s2, $s0, $t0 + lw $s2, 0($s2) # s2 = tmp = 'pivot' = v[n] + + subi $s1, $a1, 1 # s1 = i = n - 1 + +insert_loop: + blt $s1, $a0, done_insert_loop # i < k, done loop + sll $t0, $s1, 2 + add $t0, $s0, $t0 # t0 = &v[i] + lw $t1, 0($t0) + sw $t1, 4($t0) + + subi $s1, $s1, 1 # i-- + j insert_loop +done_insert_loop: + sll $t0, $a0, 2 + add $t0, $s0, $t0 + sw $s2, 0($t0) # t0 = &v[k] + + lw $s0, 8($sp) + lw $s1, 4($sp) + lw $ra, 0($sp) + addi $sp, $sp, 12 + jr $ra + + +add_compare_count: + la $t0, compare_count + lw $t1, 0($t0) + addi $t1, $t1, 1 + sw $t1, 0($t0) + jr $ra + +print_num_in_buff: + la $t0, num_N + la $t2, num_buff + lw $t0, 0($t0) + li $t1, 0 +print_loop: + bge $t1, $t0, done_print_loop + + sll $a0, $t1, 2 + add $a0, $t2, $a0 + lw $a0, 0($a0) + li $v0, 1 + syscall + + la $a0, space_string + li $v0, 4 + syscall + + addi $t1, $t1, 1 + j print_loop + +done_print_loop: + la $a0, newline_string + li $v0, 4 + syscall + jr $ra From 01c334e7f707fdceb107f712b59ed9ea009f7488 Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 23:53:44 +0800 Subject: [PATCH 11/16] 2.3 --- 1/homework/exp2/merge_sort.asm | 252 +++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 1/homework/exp2/merge_sort.asm diff --git a/1/homework/exp2/merge_sort.asm b/1/homework/exp2/merge_sort.asm new file mode 100644 index 0000000..4ff8716 --- /dev/null +++ b/1/homework/exp2/merge_sort.asm @@ -0,0 +1,252 @@ +.data +compare_count: .word 0 +num_N: .word 0 +input_file_name: .asciiz "a.in" + .align 2 +output_file_name: .asciiz "a.out" + .align 2 +space_string: .asciiz " " + .align 2 +newline_string: .asciiz "\r\n" + .align 2 +num_buff: .space 4096 + .align 2 + +.text +main: + la $a0, input_file_name + li $a1, 0 + li $a2, 0 + li $v0, 13 + syscall + + move $a0, $v0 # start to read in N + la $a1, num_N + li $a2, 4 + li $v0, 14 + syscall + + la $t0, num_N # read N * 4 bytes into num_buff + lw $a2, 0($t0) # read in num_N + sll $a2, $a2, 2 # n * 4 is the bytes to read + + la $a1, num_buff + + li $v0, 14 + syscall # read in file + li $v0, 16 + syscall # close file + + la $t0, num_N + lw $s0, 0($t0) # s0 = N + li $a0, 8 + li $v0, 9 + syscall + move $s2, $v0 # headptr in s2 + move $s3, $s2 # curnodeptr = headptr + + li $s1, 0 # s1 = index + la $t0, num_buff +create_linked_list: + bge $s1, $s0, done_create_linked_list + li $v0, 9 + syscall # new int[2] + + sw $v0, 4($s3) # curnodeptr[1] = new int[2] + move $s3, $v0 # curnodeptr = curnodeptr[1] + + sll $t1, $s1, 2 # curnodeptr[0] = num_buffer[index] + add $t1, $t0, $t1 + lw $t1, 0($t1) + sw $t1, 0($s3) + + sw $zero, 4($s3) # curnodeptr[1] = NULL + + addi $s1, $s1, 1 + j create_linked_list +done_create_linked_list: + # lw $a0, 4($s2) #a0 = headnodeptr[1] + # jal print_num + lw $a0, 4($s2) #a0 = headnodeptr[1] + jal merge_sort + sw $v0, 4($s2) + move $s1, $s2 # curptr = headptr + # lw $a0, 4($s2) #a0 = headnodeptr[1] + # jal print_num + + la $a0, output_file_name + li $a1, 1 + li $a2, 0 + li $v0, 13 + syscall + + move $a0, $v0 + la $a1, compare_count + li $a2, 4 + li $v0, 15 + syscall + +write_linked_list: + lw $s1, 4($s1) # curptr = curptr[1] + beq $s1, $zero, done_write_linked_list + move $a1, $s1 + li $v0, 15 + syscall + j write_linked_list +done_write_linked_list: + li $v0, 16 + syscall + + li $v0, 17 + syscall # exit + +merge_sort: # a0: headnodeptr + subi $sp, $sp, 20 + sw $s0, 16($sp) + sw $s1, 12($sp) + sw $s2, 8($sp) + sw $s3, 4($sp) + sw $ra, 0($sp) + + lw $t0, 4($a0) # t0 = headnodeptr[1] + bne $t0, $zero, valid_head # if headnodeptr[1] != NULL, valid head + move $v0, $a0 # no valid head + j done_merge_sort +valid_head: + move $s1, $a0 # stride 1 pointer + move $s2, $a0 # stride 2 pointer +find_mid: + lw $s2, 4($s2) # s2 = s2[1] + beq $s2, $zero, done_find_mid # s2 == NULL, break + lw $s2, 4($s2) # s2 = s2[1] + beq $s2, $zero, done_find_mid # s2 == NULL, break + lw $s1, 4($s1) + j find_mid +done_find_mid: + lw $s2, 4($s1) # now s2 is the headnodeptr of the right part + sw $zero, 4($s1) + jal merge_sort # no need to set a0 to head, it already is + move $s1, $v0 # save the result of first merge_sort to s1 + + move $a0, $s2 + jal merge_sort # merge_sort for right part + + # move $a0, $s1 + # jal print_num + + # move $a0, $v0 + # jal print_num + + move $a0, $s1 + move $a1, $v0 + jal merge_list + +done_merge_sort: + lw $s0, 16($sp) + lw $s1, 12($sp) + lw $s2, 8($sp) + lw $s3, 4($sp) + lw $ra, 0($sp) + addi $sp, $sp, 20 + jr $ra + +merge_list: # a0: l_head, a1: r_head + subi $sp, $sp, 28 + sw $s0, 24($sp) + sw $s1, 20($sp) + sw $s2, 16($sp) + sw $s3, 12($sp) + sw $s4, 8($sp) + sw $s5, 4($sp) + sw $ra, 0($sp) + + move $s0, $a0 # lheadptr + move $s1, $a1 # s1 = rheadptr + + li $a0, 8 + li $v0, 9 + syscall # create dummy node + + sw $s0, 4($v0) # headnodeptr[1] = lheadptr + move $s0, $v0 # p_left = headnodeptr; p_right = rightptr, no change. + move $s7, $v0 # head +do_merge_list: # outer while +find_left_merge_pos: + lw $s2, 4($s0) #p_left[1] + beq $s2, $zero, direct_add_right_part + jal add_compare_count + lw $s2, 0($s2) # (p_left[1])[0] + lw $t0, 0($s1) # p_right[0] + bgt $s2, $t0, no_direct_add_right_part + lw $s0, 4($s0) + j find_left_merge_pos +direct_add_right_part: + sw $s1, 4($s0) + j done_do_merge_list +no_direct_add_right_part: + move $s2, $s1 # p_right_temp + lw $s5, 4($s0) + lw $s5, 0($s5) # (p_left[1])[0] +find_right_merge_pos: + lw $s3, 4($s2) # p_right_temp[1] + beq $s3, $zero, done_find_right_merge_pos + jal add_compare_count + lw $s4, 0($s3) # (p_right_temp[1])[0] + bgt $s4, $s5, done_find_right_merge_pos + move $s2, $s3 # p_right_temp = p_right_temp[1] + j find_right_merge_pos +done_find_right_merge_pos: + move $s4, $s3 # temp_right_pointer_next + lw $t0, 4($s0) # p_left[1] + sw $t0, 4($s2) # p_right_temp[1] = p_left[1] + sw $s1, 4($s0) # p_left[1] = p_right + move $s0, $s2 + move $s1, $s4 + beq $s1, $zero, done_do_merge_list + j do_merge_list +done_do_merge_list: + lw $v0, 4($s7) + +done_merge_list: + lw $s0, 24($sp) + lw $s1, 20($sp) + lw $s2, 16($sp) + lw $s3, 12($sp) + lw $s4, 8($sp) + lw $s5, 4($sp) + lw $ra, 0($sp) + addi $sp, $sp, 28 + jr $ra + +add_compare_count: + la $t0, compare_count + lw $t1, 0($t0) + addi $t1, $t1, 1 + sw $t1, 0($t0) + jr $ra + +print_num: #a0: headptr + subi $sp, $sp, 8 + sw $t0, 4($sp) + sw $v0, 0($sp) + + move $t0, $a0 +print_loop: + lw $a0, 0($t0) + li $v0, 1 + syscall + la $a0, space_string + li $v0, 4 + syscall + lw $t0, 4($t0) + beq $t0, $zero, done_print_num + j print_loop +done_print_num: + la $a0, newline_string + li $v0, 4 + syscall + + lw $t0, 4($sp) + lw $v0, 0($sp) + addi $sp, $sp, 8 + jr $ra \ No newline at end of file From 182a6eb8ae49785953f701831d2b605eb0840dc9 Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 3 May 2024 23:54:32 +0800 Subject: [PATCH 12/16] Add a correct answer for reference. --- 1/homework/exp2/a.out.correct | Bin 0 -> 84 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 1/homework/exp2/a.out.correct diff --git a/1/homework/exp2/a.out.correct b/1/homework/exp2/a.out.correct new file mode 100644 index 0000000000000000000000000000000000000000..b223727c06a247b7c6867f1647e61fb90a529e34 GIT binary patch literal 84 zcmWN@Ar687006)X7B&-!KM;%z$Jp2iT5R|sGGzS$fyl-KOm+$o`GFr0!flu1apE5k lpJ_tM3%7(Q<#*+o5f*fZ>dxHqezEk_ Date: Fri, 3 May 2024 23:57:11 +0800 Subject: [PATCH 13/16] Better format. --- 1/homework/exp1/exp1_1.asm | 72 +++++++++++------------ 1/homework/exp1/exp1_2.asm | 39 +++++++------ 1/homework/exp1/exp1_3.asm | 102 ++++++++++++++++----------------- 1/homework/exp1/exp1_4.asm | 54 ++++++++--------- 1/homework/exp2/merge_sort.asm | 2 +- 5 files changed, 136 insertions(+), 133 deletions(-) diff --git a/1/homework/exp1/exp1_1.asm b/1/homework/exp1/exp1_1.asm index cf589eb..a006adf 100644 --- a/1/homework/exp1/exp1_1.asm +++ b/1/homework/exp1/exp1_1.asm @@ -1,42 +1,42 @@ -.data -file_buff: .space 8 # A space of 2 bytes -.align 3 -input_file_name: .asciiz "a.in" -.align 3 -output_file_name: .asciiz "a.out" -.align 3 -.text +.data +file_buff: .space 8 # A space of 2 bytes + .align 3 +input_file_name: .asciiz "a.in" + .align 3 +output_file_name: .asciiz "a.out" + .align 3 +.text -la $a0, input_file_name -li $a1, 0 # set mode as read -li $a2, 0 # meaning nothing, really -li $v0, 13 # open file -syscall #now $v0 is the file handler +la $a0, input_file_name +li $a1, 0 # set mode as read +li $a2, 0 # meaning nothing, really +li $v0, 13 # open file +syscall #now $v0 is the file handler -move $a0, $v0 #move file handler to a0 as first syscall arg -la $a1, file_buff -li $a2, 8 # read in 8 bytes -li $v0, 14 +move $a0, $v0 #move file handler to a0 as first syscall arg +la $a1, file_buff +li $a2, 8 # read in 8 bytes +li $v0, 14 syscall -li $v0, 16 -syscall # close file +li $v0, 16 +syscall # close file -la $a0, output_file_name -li $a1, 1 # set mode as write -li $a2, 0 # meaning nothing, really -li $v0, 13 # open file -syscall +la $a0, output_file_name +li $a1, 1 # set mode as write +li $a2, 0 # meaning nothing, really +li $v0, 13 # open file +syscall -move $a0, $v0 -la $a1, file_buff -li $a2, 8 # write 8 bytes -li $v0, 15 # write file -syscall -li $v0, 16 -syscall +move $a0, $v0 +la $a1, file_buff +li $a2, 8 # write 8 bytes +li $v0, 15 # write file +syscall +li $v0, 16 +syscall -li $v0 5 # read integer -syscall -addi $a0, $v0, 10 # a0 = v0 + 10 -li $v0 1 # print integer -syscall +li $v0, 5 # read integer +syscall +addi $a0, $v0, 10 # a0 = v0 + 10 +li $v0, 1 # print integer +syscall diff --git a/1/homework/exp1/exp1_2.asm b/1/homework/exp1/exp1_2.asm index a07ab41..fd16023 100644 --- a/1/homework/exp1/exp1_2.asm +++ b/1/homework/exp1/exp1_2.asm @@ -1,26 +1,29 @@ .data .text -li $v0, 5 # read in i -syscall -move $s1, $v0 # use s1 to store i + li $v0, 5 # read in i + syscall + move $s1, $v0 # use s1 to store i -li $v0, 5 # read in j -syscall -move $s2, $v0 # use s2 to store j + li $v0, 5 # read in j + syscall + move $s2, $v0 # use s2 to store j -sub $s1, $zero, $s1 # i = -i + sub $s1, $zero, $s1 # i = -i -bgez $s2, no_neg_j # if >= 0, then no neg -sub $s2, $zero, $s2 # j = -j + bgez $s2, no_neg_j # if >= 0, then no neg + sub $s2, $zero, $s2 # j = -j -no_neg_j: move $s0, $zero # use s0 as temp, temp = 0 -count_up_j: bge $s0, $s2, done_count_up # if temp >= j, stop iteration -addi $s1, $s1, 1 # i = i + 1 -addi $s0, $s0, 1 # ++temp -j count_up_j +no_neg_j: + move $s0, $zero # use s0 as temp, temp = 0 +count_up_j: + bge $s0, $s2, done_count_up # if temp >= j, stop iteration + addi $s1, $s1, 1 # i = i + 1 + addi $s0, $s0, 1 # ++temp + j count_up_j -done_count_up: move $a0, $s1 -li $v0 1 -syscall +done_count_up: + move $a0, $s1 + li $v0, 1 + syscall -move $v0, $s1 # set return value \ No newline at end of file + move $v0, $s1 # set return value \ No newline at end of file diff --git a/1/homework/exp1/exp1_3.asm b/1/homework/exp1/exp1_3.asm index 3f05bcb..3b1ecc9 100644 --- a/1/homework/exp1/exp1_3.asm +++ b/1/homework/exp1/exp1_3.asm @@ -1,66 +1,66 @@ .data .text -li $v0 5 # read in num -syscall + li $v0, 5 # read in num + syscall -move $s0, $v0 # $s0 is n -move $a0, $v0 -li $v0, 9 # malloc -syscall -move $s1, $v0 # $s1 = a + move $s0, $v0 # $s0 is n + move $a0, $v0 + li $v0, 9 # malloc + syscall + move $s1, $v0 # $s1 = a -move $t0, $zero # a0 = 0 + move $t0, $zero # a0 = 0 -move $t0, $zero # i = 0 -move $t1, $s1 #t1 = a -read_in_num: - bge $t0, $s0, done_read_in_num # i >= n, break - li $v0, 5 # read in num - syscall + move $t0, $zero # i = 0 + move $t1, $s1 #t1 = a +read_in_num: + bge $t0, $s0, done_read_in_num # i >= n, break + li $v0, 5 # read in num + syscall - sw $v0, 0($t1) # a[i] = v0 - addi $t0, $t0, 1 # i++ - addi $t1, $t1, 4 # t1 += 4 - j read_in_num + sw $v0, 0($t1) # a[i] = v0 + addi $t0, $t0, 1 # i++ + addi $t1, $t1, 4 # t1 += 4 + j read_in_num -done_read_in_num: -srl $s2, $s0, 1 # s1 = n / 2 -move $t0, $zero # i = 0 -move $t1, $s1 +done_read_in_num: + srl $s2, $s0, 1 # s1 = n / 2 + move $t0, $zero # i = 0 + move $t1, $s1 -subi $t2, $s0, 1 # t2 = n - 1 -sll $t2, $t2, 2 # t2 *= 4 -add $t2, $t2, $s1 -reverse: - bge $t0, $s2, done_reverse # i >= n / 2, break - lw $t3, 0($t1) # t3 = a[i] - addi $t3, $t3, 1 # t3 += 1 + subi $t2, $s0, 1 # t2 = n - 1 + sll $t2, $t2, 2 # t2 *= 4 + add $t2, $t2, $s1 +reverse: + bge $t0, $s2, done_reverse # i >= n / 2, break + lw $t3, 0($t1) # t3 = a[i] + addi $t3, $t3, 1 # t3 += 1 - lw $t4, 0($t2) # t4 = a[n - i - 1] - addi $t4, $t4, 1 # t4 += 1 + lw $t4, 0($t2) # t4 = a[n - i - 1] + addi $t4, $t4, 1 # t4 += 1 - sw $t4, 0($t1) - sw $t3, 0($t2) + sw $t4, 0($t1) + sw $t3, 0($t2) - addi $t0, $t0, 1 - addi $t1, $t1, 4 - subi $t2, $t2, 4 - j reverse + addi $t0, $t0, 1 + addi $t1, $t1, 4 + subi $t2, $t2, 4 + j reverse -done_reverse: -move $t0, $zero -move $t1, $s1 +done_reverse: + move $t0, $zero + move $t1, $s1 -output: - bge $t0, $s0 done_output - lw $a0, 0($t1) - li $v0 1 - syscall +output: + bge $t0, $s0, done_output + lw $a0, 0($t1) + li $v0, 1 + syscall - addi $t0, $t0, 1 - addi $t1, $t1, 4 - j output + addi $t0, $t0, 1 + addi $t1, $t1, 4 + j output -done_output: -li $v0 17 -syscall \ No newline at end of file +done_output: + li $v0, 17 + syscall \ No newline at end of file diff --git a/1/homework/exp1/exp1_4.asm b/1/homework/exp1/exp1_4.asm index e2c91f6..48d9240 100644 --- a/1/homework/exp1/exp1_4.asm +++ b/1/homework/exp1/exp1_4.asm @@ -2,34 +2,34 @@ .text main: - li $v0, 5 # read in - syscall - move $s0, $v0 # s0 is the n - move $a0, $s0 # set the first call arg as n - jal hanoi # call proc - move $a0, $v0 # print out - li $v0, 1 - syscall - li $v0, 17 - syscall + li $v0, 5 # read in + syscall + move $s0, $v0 # s0 is the n + move $a0, $s0 # set the first call arg as n + jal hanoi # call proc + move $a0, $v0 # print out + li $v0, 1 + syscall + li $v0, 17 + syscall hanoi: - li $t0, 1 - ble $a0, $t0, hanoi_bottom # if n <= 1, return - j hanoi_recur + li $t0, 1 + ble $a0, $t0, hanoi_bottom # if n <= 1, return + j hanoi_recur hanoi_bottom: - li $v0, 1 # return 1 - jr $ra + li $v0, 1 # return 1 + jr $ra hanoi_recur: - subi $sp, $sp, 8 # move sp down by 2 word - sw $s0, 4($sp) # first word is the n in caller - sw $ra, 0($sp) # second word is the return addr of this callee - move $s0, $a0 - subi $a0, $s0, 1 - jal hanoi - sll $v0, $v0, 1 # hanoi(n - 1) * 2 - ori $v0, $v0, 1 # hanoi(n - 1) * 2 + 1 - lw $s0, 4($sp) # reverse s0 - lw $ra, 0($sp) # reverse ra - addi $sp, $sp, 8 - jr $ra + subi $sp, $sp, 8 # move sp down by 2 word + sw $s0, 4($sp) # first word is the n in caller + sw $ra, 0($sp) # second word is the return addr of this callee + move $s0, $a0 + subi $a0, $s0, 1 + jal hanoi + sll $v0, $v0, 1 # hanoi(n - 1) * 2 + ori $v0, $v0, 1 # hanoi(n - 1) * 2 + 1 + lw $s0, 4($sp) # reverse s0 + lw $ra, 0($sp) # reverse ra + addi $sp, $sp, 8 + jr $ra diff --git a/1/homework/exp2/merge_sort.asm b/1/homework/exp2/merge_sort.asm index 4ff8716..936f530 100644 --- a/1/homework/exp2/merge_sort.asm +++ b/1/homework/exp2/merge_sort.asm @@ -181,7 +181,7 @@ find_left_merge_pos: lw $s0, 4($s0) j find_left_merge_pos direct_add_right_part: - sw $s1, 4($s0) + sw $s1, 4($s0) j done_do_merge_list no_direct_add_right_part: move $s2, $s1 # p_right_temp From d337b65362a68decedd1fe9ac1f50307d067eeaf Mon Sep 17 00:00:00 2001 From: unlockable Date: Sat, 4 May 2024 10:31:11 +0800 Subject: [PATCH 14/16] Add return 0 at the end of excution. --- 1/homework/exp1/exp1_3.asm | 1 + 1/homework/exp1/exp1_4.asm | 1 + 1/homework/exp2/binary_insert_sort.asm | 1 + 1/homework/exp2/insert_sort.asm | 1 + 1/homework/exp2/merge_sort.asm | 1 + 5 files changed, 5 insertions(+) diff --git a/1/homework/exp1/exp1_3.asm b/1/homework/exp1/exp1_3.asm index 3b1ecc9..bc51779 100644 --- a/1/homework/exp1/exp1_3.asm +++ b/1/homework/exp1/exp1_3.asm @@ -62,5 +62,6 @@ output: j output done_output: + li $a0, 0 li $v0, 17 syscall \ No newline at end of file diff --git a/1/homework/exp1/exp1_4.asm b/1/homework/exp1/exp1_4.asm index 48d9240..43c9e5f 100644 --- a/1/homework/exp1/exp1_4.asm +++ b/1/homework/exp1/exp1_4.asm @@ -10,6 +10,7 @@ main: move $a0, $v0 # print out li $v0, 1 syscall + li $a0, 0 li $v0, 17 syscall diff --git a/1/homework/exp2/binary_insert_sort.asm b/1/homework/exp2/binary_insert_sort.asm index 6f6949f..5fcd23f 100644 --- a/1/homework/exp2/binary_insert_sort.asm +++ b/1/homework/exp2/binary_insert_sort.asm @@ -61,6 +61,7 @@ main: li $v0, 15 syscall + li $a0, 0 li $v0, 17 syscall # exit diff --git a/1/homework/exp2/insert_sort.asm b/1/homework/exp2/insert_sort.asm index 64522f7..1b79f69 100644 --- a/1/homework/exp2/insert_sort.asm +++ b/1/homework/exp2/insert_sort.asm @@ -58,6 +58,7 @@ main: li $v0, 15 syscall + li $a0, 0 li $v0, 17 syscall # exit diff --git a/1/homework/exp2/merge_sort.asm b/1/homework/exp2/merge_sort.asm index 936f530..868829a 100644 --- a/1/homework/exp2/merge_sort.asm +++ b/1/homework/exp2/merge_sort.asm @@ -97,6 +97,7 @@ done_write_linked_list: li $v0, 16 syscall + li $a0, 0 li $v0, 17 syscall # exit From d92edc05165247788b5d8c2999cba6f0e7e890d8 Mon Sep 17 00:00:00 2001 From: unlockable Date: Sat, 4 May 2024 10:59:48 +0800 Subject: [PATCH 15/16] Request for correct amount of memory. --- 1/homework/exp1/exp1_3.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1/homework/exp1/exp1_3.asm b/1/homework/exp1/exp1_3.asm index bc51779..4bd84c2 100644 --- a/1/homework/exp1/exp1_3.asm +++ b/1/homework/exp1/exp1_3.asm @@ -4,7 +4,7 @@ syscall move $s0, $v0 # $s0 is n - move $a0, $v0 + sll $a0, $v0, 2 li $v0, 9 # malloc syscall move $s1, $v0 # $s1 = a From 5befba6b866fe20ebc9c503c5782b6b1b7858d4e Mon Sep 17 00:00:00 2001 From: unlockable Date: Sat, 4 May 2024 14:42:21 +0800 Subject: [PATCH 16/16] Add report --- .gitignore | 7 +++- 1/homework/report.tex | 85 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 1/homework/report.tex diff --git a/.gitignore b/.gitignore index 85ccd6c..ef7ff68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ *.zip *.pdf */attachment/ -*.docx \ No newline at end of file +*.docx +*.out +*.aux +*.log +*.synctex(busy) +*.synctex.gz \ No newline at end of file diff --git a/1/homework/report.tex b/1/homework/report.tex new file mode 100644 index 0000000..be3a09b --- /dev/null +++ b/1/homework/report.tex @@ -0,0 +1,85 @@ +\documentclass[11pt, a4paper]{article} +\usepackage[UTF8]{ctex} +\usepackage{geometry} +\usepackage[inline]{enumitem} +\usepackage{amsmath} +\usepackage{float} +\usepackage{listings} +\usepackage{fontspec} +\usepackage{xcolor} + +% \newfontfamily\codefont[Ligatures=ResetAll]{Fira Code}[Contextuals={Alternate}] +\newfontfamily\codefont{Cascadia Code} + +\lstset{ + basicstyle = \small\codefont, + % --- + tabsize = 4, + showstringspaces = false, + numbers = left, + numberstyle = \codefont, + % --- + breaklines = true, + captionpos = t, + % --- + frame = l, + flexiblecolumns, + columns = fixed, +} + +\lstdefinestyle{asmstyle}{ + % basicstyle = \small\codefont, + keywordstyle=\bfseries\color{green!40!black}, + commentstyle=\color{purple!40!black}, + identifierstyle=\color{blue!80!white}, +} + +\title{\textbf{Report for First Assembly Homework}} +\author{2022010639 高艺轩} +\date{} + +\begin{document} +\maketitle +\section{Basic Exercises} +\subsection{System Call} +The code is essentially a set of system calls. Set the values in \lstinline{$a0, $a1, $a2} as the arguments to pass to the operation system, and use \lstinline{$v0} to change the exact systemcall. + +These systemcalls first open file as read only, then read the contents into the memory; close the file, then open another file in write only mode and write the content just read from the other file. + +The last two systemcalls are reading from \lstinline{stdin} and output to \lstinline{stdout}, respectively. + +\subsection{Loop and Branch} +The \lstinline{for} loop and \lstinline{if} clause in high level programming language is written in a way that we write the action to do when the expression is satisfied at the top, and then write the other part after that. However, to achieve similar structure in assembly code, we have to compose the logic in the way of ``If the expression is NOT met, then jump further away so the instructions right behind this jump instruction is NOT executed'', and by this way, when the expression is met, \lstinline{pc} won't be altered and the code below will be executed. + +The program first read in \lstinline{i} and \lstinline{j} from \lstinline{stdin}, then use a \lstinline{bgez} to decided whether \lstinline{j = -j} needed to be executed. Then, set a register as temp, and count it up to add 1 to \lstinline{i} every time until temp is greater than or equal to (\lstinline{bge}) \lstinline{j}. Lastly, print out the result and set the return value. + +\subsection{Array and Pointer} +First, read in the total number \lstinline{n} of the upcoming numbers; Then, request \lstinline{n << 2} bytes of space to store the numbers. Use \lstinline{$t0} as the counter, and \lstinline{$t1} as the pointer, write the number read into memory. Doing the reverse is similar to this. Every iteration adds \lstinline{$t1} by 4 and subtracts \lstinline{$t2} by 4 so that \lstinline{a[i]} and \lstinline{a[n - i - 1]} can be accessed. At last, cycle through the number once more to output the results. + +\subsection{Function Call} +Function call is actually very similar to what it is in higher level language. The only difference is that inside a procedure call, first move \lstinline{$sp} by some distance and store all the registers that are required to be preserved but also used by this procedure call, including \lstinline{$ra}. Then write the procedure as if it is a normal program, the arguments of the call is stored in \lstinline{$a0, $a1, $a2} and should be copied to saved registers if needed later. At the end of the procedure, save the return value to \lstinline{$v0}, restore all the saved register value from stack and restore \lstinline{$sp} then call \lstinline{jr $ra} to return. + +\section{Practical Application} +\subsection{Direct Insertion Sort} +In \lstinline{insertion_sort}, \lstinline{$s0} is the \lstinline{n}, \lstinline{$s1} is the \lstinline{i} in \lstinline{for} loop. For every element in the list, the procedure uses \lstinline{search} to find its correct position, and use insert to insert it into that position. + +In \lstinline{search}, \lstinline{$s0} is \lstinline{&v[0]} and \lstinline{$s2} is \lstinline{v[n]}, \lstinline{$s1} is \lstinline{i} in the \lstinline{search_loop}. The procedure finds the first number that is smaller than the target number, and return the address of one after this smaller number. + +In \lstinline{insert}, \lstinline{$s0 = &v[0]}, \lstinline{$s2 = v[n]}, \lstinline{$s1 = i}, string from \lstinline{n - 1}. The procedure moves everything after the target's correct position one slot backward, and then insert the target into its correct position. + +In \lstinline{add_compare_count}, the procedure loads the stored compare count, add 1 to it, and then write it back to memory. + +\lstinline{print_num_in_buff} is a procedure used for debugging. It prints out all the number in the number buffer, seperated by space and ended by \lstinline{\r\n}. + +\subsection{Binary Insertion Sort} +The overall design and structure of the program is same as the `Direct Insertion Sort'. The only difference is that the \lstinline{search} procedure now uses binary search to search for the correct position of the target number. + +In the new \lstinline{binary_search} procedure, \lstinline{$s1 = left}, \lstinline{$s2 = right}, \lstinline{$s3 = mid}, and \lstinline{$t0 = &v[0]}, \lstinline{$t1 = v[mid]}, \lstinline{$t2 = v[n] = target_number}. Every time the procedure finds the number in the middle of left and right and compare it with the target number; if the middle number is larger, then further search for left part; if the middle number is smaller, then further search for right part. Do this recursively until the left bound is larger than right bound, which means the left bound is the position to insert this target number. + +\subsection{Merge Sort} +The C++ code uses linked list, and thus the \lstinline{main} part of the code have to create the linked list after reading the file into the memory. For every number, allocate a new node on heap, then save the pointer and content. Then it calls \lstinline{merge_sort} and save the sort result into file. + +In \lstinline{merge_sort}, \lstinline{$s1} is the stride 1 pointer and \lstinline{$s2} is the stride 2 pointer that goes 2 steps every 1 step the stride 1 pointer tooks. When stride 2 pointer reaches the end of the list, stride 1 pointer is pointing at the middle of the list. Then it breaks the list at the middle, and calls \lstinline{merge_sort} on both parts. Then, use \lstinline{merge_list} to merge back the two parts into a ordered list. + +In \lstinline{merge_list}, \lstinline{$s0} is the \lstinline{p_left}, \lstinline{$s1} is the \lstinline{p_right}, and \lstinline{$s7} is the \lstinline{head}. \lstinline{$s2, $s3, $s4, $s5} are used according to the needs, they are typically \lstinline{p_left[1]}, or \lstinline{(p_left[1])[0]}, or \lstinline{p_right_temp}, which are labeled in comments. In essence, the proceture takes two ordered list and reconnect them to combine them into one ordered list. +\end{document} \ No newline at end of file