diff --git a/seminaries/qtmips/call-syscall/lec10-01-call4-clobber.S b/seminaries/qtmips/call-syscall/lec10-01-call4-clobber.S new file mode 100644 index 0000000000000000000000000000000000000000..b005ff0a2e2b841376f73a229927353fb135acd0 --- /dev/null +++ b/seminaries/qtmips/call-syscall/lec10-01-call4-clobber.S @@ -0,0 +1,39 @@ +// select core without pipeline but with delay slot + +#pragma qtmips show registers +#pragma qtmips show memory +#pragma qtmips show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +.set noreorder +.text + +main: + la $sp, STACK_INIT + li $s0, 0x12345678 + addi $a0, $0, 2 + addi $a1, $0, 3 + addi $a2, $0, 4 + addi $a3, $0, 5 + jal fun + nop + add $t0, $v0, $0 + sw $t0, SPILED_REG_LED_LINE($0) +final: + break + beq $0, $0, final + +// int fun(int g, h, i, j) +// g→$a0, h→$a1, i→$a2, j→$a3, $v0 – ret. val, $sX – save, $tX – temp, $ra – ret. addr +// return (g + h) – (i + j) +fun: + add $t0, $a0, $a1 + add $t1, $a2, $a3 + sub $s0, $t0, $t1 + add $v0, $s0, $0 + jr $ra + nop + +#pragma qtmips focus memory STACK_INIT-4*8 diff --git a/seminaries/qtmips/call-syscall/lec10-02-call4-save.S b/seminaries/qtmips/call-syscall/lec10-02-call4-save.S new file mode 100644 index 0000000000000000000000000000000000000000..f65861eab1ff6dd58ff1e9ab6dfad3fd74a963ea --- /dev/null +++ b/seminaries/qtmips/call-syscall/lec10-02-call4-save.S @@ -0,0 +1,43 @@ +// select core without pipeline but with delay slot + +#pragma qtmips show registers +#pragma qtmips show memory +#pragma qtmips show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +.set noreorder +.text + +main: + la $sp, STACK_INIT + li $s0, 0x12345678 + addi $a0, $0, 2 + addi $a1, $0, 3 + addi $a2, $0, 4 + addi $a3, $0, 5 + jal fun + nop + add $t0, $v0, $0 + sw $t0, SPILED_REG_LED_LINE($0) +final: + break + beq $0, $0, final + +// int fun(int g, h, i, j) +// g→$a0, h→$a1, i→$a2, j→$a3, $v0 – ret. val, $sX – save, $tX – temp, $ra – ret. addr +// return (g + h) – (i + j) +fun: + addi $sp, $sp, -4 + sw $s0, 0($sp) // Save $s0 on stack + add $t0, $a0, $a1 + add $t1, $a2, $a3 // Procedure body + sub $s0, $t0, $t1 + add $v0, $s0, $zero // Result + lw $s0, 0($sp) // Restore $s0 + addi $sp, $sp, 4 + jr $ra // Return + nop + +#pragma qtmips focus memory STACK_INIT-4*8 diff --git a/seminaries/qtmips/call-syscall/lec10-03-fact-buggy.S b/seminaries/qtmips/call-syscall/lec10-03-fact-buggy.S new file mode 100644 index 0000000000000000000000000000000000000000..6476fdde156ebc48b59f3a7bebaaeb067747fb7a --- /dev/null +++ b/seminaries/qtmips/call-syscall/lec10-03-fact-buggy.S @@ -0,0 +1,43 @@ +// select core without pipeline but with delay slot + +#pragma qtmips show registers +#pragma qtmips show memory +#pragma qtmips show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +.set noreorder +.text + +main: + la $sp, STACK_INIT + addi $a0, $0, 4 // 4! -> 24 + jal fact + nop + add $s0, $v0, $0 + sw $s0, SPILED_REG_LED_LINE($0) +final: + break + beq $0, $0, final + nop + +fact: + addi $sp, $sp, -4 // adjust stack for 2 items + sw $a0, 0($sp) // save argument + slti $t0, $a0, 1 // test for n < 1 + beq $t0, $zero, L1 + addi $v0, $zero, 1 // if so, result is 1 + addi $sp, $sp, 4 // pop 2 items from stack + jr $ra // and return + nop +L1: addi $a0, $a0, -1 // else decrement n + jal fact // recursive call + nop + lw $a0, 0($sp) // restore original n + addi $sp, $sp, 4 // pop 2 items from stack + mul $v0, $a0, $v0 // multiply to get result + jr $ra // and return + nop + +#pragma qtmips focus memory STACK_INIT-4*8 diff --git a/seminaries/qtmips/call-syscall/lec10-04-fact-ok.S b/seminaries/qtmips/call-syscall/lec10-04-fact-ok.S new file mode 100644 index 0000000000000000000000000000000000000000..6c3e8dc32c5042fc87ff7460ac82b7d8249ab5ac --- /dev/null +++ b/seminaries/qtmips/call-syscall/lec10-04-fact-ok.S @@ -0,0 +1,45 @@ +// select core without pipeline but with delay slot + +#pragma qtmips show registers +#pragma qtmips show memory +#pragma qtmips show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +.set noreorder +.text + +main: + la $sp, STACK_INIT + addi $a0, $0, 4 // 4! -> 24 + jal fact + nop + add $s0, $v0, $0 + sw $s0, SPILED_REG_LED_LINE($0) +final: + break + beq $0, $0, final + nop + +fact: + addi $sp, $sp, -8 // adjust stack for 2 items + sw $ra, 4($sp) // save return address + sw $a0, 0($sp) // save argument + slti $t0, $a0, 1 // test for n < 1 + beq $t0, $zero, L1 + addi $v0, $zero, 1 // if so, result is 1 + addi $sp, $sp, 8 // pop 2 items from stack + jr $ra // and return + nop +L1: addi $a0, $a0, -1 // else decrement n + jal fact // recursive call + nop + lw $a0, 0($sp) // restore original n + lw $ra, 4($sp) // and return address + addi $sp, $sp, 8 // pop 2 items from stack + mul $v0, $a0, $v0 // multiply to get result + jr $ra // and return + nop + +#pragma qtmips focus memory STACK_INIT-4*8 diff --git a/seminaries/qtmips/call-syscall/lec10-05-call-6args.S b/seminaries/qtmips/call-syscall/lec10-05-call-6args.S new file mode 100644 index 0000000000000000000000000000000000000000..6c3e8dc32c5042fc87ff7460ac82b7d8249ab5ac --- /dev/null +++ b/seminaries/qtmips/call-syscall/lec10-05-call-6args.S @@ -0,0 +1,45 @@ +// select core without pipeline but with delay slot + +#pragma qtmips show registers +#pragma qtmips show memory +#pragma qtmips show peripherals + +.equ SPILED_REG_LED_LINE, 0xffffc104 // 32 bit word mapped as output +.equ STACK_INIT, 0x01230000 // The bottom of the stack, the stack grows down + +.set noreorder +.text + +main: + la $sp, STACK_INIT + addi $a0, $0, 4 // 4! -> 24 + jal fact + nop + add $s0, $v0, $0 + sw $s0, SPILED_REG_LED_LINE($0) +final: + break + beq $0, $0, final + nop + +fact: + addi $sp, $sp, -8 // adjust stack for 2 items + sw $ra, 4($sp) // save return address + sw $a0, 0($sp) // save argument + slti $t0, $a0, 1 // test for n < 1 + beq $t0, $zero, L1 + addi $v0, $zero, 1 // if so, result is 1 + addi $sp, $sp, 8 // pop 2 items from stack + jr $ra // and return + nop +L1: addi $a0, $a0, -1 // else decrement n + jal fact // recursive call + nop + lw $a0, 0($sp) // restore original n + lw $ra, 4($sp) // and return address + addi $sp, $sp, 8 // pop 2 items from stack + mul $v0, $a0, $v0 // multiply to get result + jr $ra // and return + nop + +#pragma qtmips focus memory STACK_INIT-4*8 diff --git a/seminaries/qtmips/call-syscall/lec10-06-linus-hello.S b/seminaries/qtmips/call-syscall/lec10-06-linus-hello.S new file mode 100644 index 0000000000000000000000000000000000000000..083a71bf6af00df11b030fa70add9b9c314f1d09 --- /dev/null +++ b/seminaries/qtmips/call-syscall/lec10-06-linus-hello.S @@ -0,0 +1,63 @@ +// The first program run by Linus on MIPS Linux kernel port + + +// select core without pipeline but with delay slot + +#pragma qtmips show registers +#pragma qtmips show memory +#pragma qtmips show terminal + +// #include <asm/unistd.h> +// #include <asm/asm.h> +// #include <sys/syscall.h> + +.equ O_RDWR, 02 + +// Linux kernel compatible system calls subset + +.equ SYS_exit, 4001 // void exit(int status) +.equ SYS_read, 4003 // ssize_t read(int fd, void *buf, size_t count) +.equ SYS_write, 4004 // ssize_t write(int fd, const void *buf, size_t count) +.equ SYS_close, 4006 // int close(int fd) +.equ SYS_open, 4005 // int open(const char *pathname, int flags, mode_t mode) +.equ SYS_brk, 4045 // void * brk(void *addr) +.equ SYS_truncate, 4092 // int ftruncate(int fd, off_t length) +.equ SYS_readv, 4145 // ssize_t readv(int fd, const struct iovec *iov, int iovcnt) +.equ SYS_writev, 4146 // ssize_t writev(int fd, const struct iovec *iov, int iovcnt) + +.set noreorder +.text + +// LEAF(main) +// fd = open("/dev/tty1", O_RDWR, 0); + la $a0, tty + li $a1, O_RDWR + li $a2, 0 + li $v0, SYS_open + syscall + bne $a3, $0, quit + addi $s0, $v0, 0 // delay slot +// write(fd, "hello, world.\n", 14); + addi $a0, $s0, 0 + la $a1, hello + li $a2, 14 + li $v0, SYS_write + syscall +// close(fd); + addi $a0, $s0, 0 + li $v0, SYS_close + syscall + +quit: + li $a0, 0 + li $v0, SYS_exit + syscall + + j quit + nop + +// END(main) + + .data +tty: .asciz "/dev/tty1" +hello: .ascii "Hello, world.\n"