程序代写代做代考 C go assembly compiler mips kernel .text

.text

# $15 – pointer to result
# $16 – pointer to current integer
# $17 – pointer to number of values

# $10 – current sum
# $11 – current integer
# $12 – current count

# initialize pointers
la $15, result
la $16, nums
la $17, count

li $10, 0 # our sum starts at 0
lw $11, 0($16) # get the initial value so we can top test the loop

lw $12, 0($17) # get the number of words to add
loop:
beq $12,$0, done # have we seen them all?
addu $10, $10, $11 # add the current value
addiu $16, $16, 4 # increment the pointer to the next word
lw $11, 0($16) # get the next value
subiu $12,$12,1 # subtract one from our count
j loop
done:
sw $10, 0($15) # store the result to memory
nop
li $v0, 10 # system call for exit
syscall # Exit!

.data
result:
.word 0x00000000
nums:
.word 0x2, 0x2, 0x2,0x2, 0x2
count:
.word 0x5
#
# YOU ARE NOT PERMITTED TO MODIFY **ANY** CODE IN THIS ASSEMBLY FILE
#

# DID YOU READ THAT? I SAID:
#
# YOU ARE ABSOTIVELY, POSOLUTELY NOT PERMITTED TO MODIFY ANY PART
# OF THIS FILE!
#

# Best to keep these next few lines all together
#
# Settings for “Bitmap Display” given the following .eqv directives…
#
# Unit width in pixels: 32; unit height in pixels: 32
# Display width in pixels: 512; display height in pixels: 512
# Base address for display: 0x10010000

.eqv WIDTH_IN_PIXELS 16
.eqv WIDTH_IN_SHIFTS 4
.eqv HEIGHT_IN_PIXELS 16
.eqv HEIGHT_IN_SHIFTS 4
.eqv PIXEL_WIDTH 1
.eqv PIXEL_WIDTH_IN_SHIFTS 2
.eqv PIXEL_HEIGHT 1
.eqv PIXEL_HEIGHT_IN_SHIFTS 0
.eqv FRAME_BUFFER_SIZE 1024 # 16 * 16 * 4 (that is, one word per pixel)

.data 0x10014000 # room for activation frames in this file
SET_PIXEL_SAVES:
.space 16
RENDER_FRAME_SAVES:
.space 12

.data 0x10010000 # All pixel operations go directly to area mapped by Bitmap tool
FRAME_BUFFER:
.space FRAME_BUFFER_SIZE

.data

.text
# Assumption here is that thie file is “included” into some other file
# and we want control to begin in that other file’s own code. We
# assume, therefore, that the other file begins the program
# at “main”.
j main

# Should never, ever, **ever** return to this spoint in the code.

# $a0: row (counting from the top as row 0)
# $a1: column (counting from the left as column 0)
# $a2: colour (24-bit RGB value)
#
# Note that this code does *not* use the stack to save and
# restore register. This is pretty much a consequence of
# paranoia — that is, by separating the following code
# from any other routines that use the stack, we isolate
# the following code from any bugs in stack-maintenance
# operations.
#
set_pixel:
la $t1, SET_PIXEL_SAVES
sw $ra, 0($t1)
sw $s0, 4($t1)
sw $s1, 8($t1)
sw $s2, 12($t1)

# sanity check: 0 <= row < HEIGHT_IN_PIXELS? 0 <= col < WIDTH_IN_PIXELS? bltz $a0, set_pixel_exit bge $a0, HEIGHT_IN_PIXELS, set_pixel_exit bltz $a1, set_pixel_exit bge $a1, WIDTH_IN_PIXELS, set_pixel_exit # Need byte address of row add $s0, $zero, $a0 sll $s0, $s0, PIXEL_WIDTH_IN_SHIFTS sll $s0, $s0, PIXEL_HEIGHT_IN_SHIFTS sll $s0, $s0, WIDTH_IN_SHIFTS # Now need offset for column in that row addi $s1, $zero, 1 sll $s1, $s1, PIXEL_WIDTH_IN_SHIFTS sll $s1, $s1, PIXEL_HEIGHT_IN_SHIFTS mult $s1, $a1 mflo $s1 # Finally, compute the address of the first byte # in that pixel. la $s2, FRAME_BUFFER add $s2, $s2, $s0 add $s2, $s2, $s1 addi $s0, $zero, PIXEL_HEIGHT set_pixel_row: addi $s1, $zero, PIXEL_WIDTH set_pixel_column: sw $a2, 0($s2) addi $s2, $s2, 4 addi $s1, $s1, -1 bne $s1, $zero, set_pixel_column addi $s1, $zero, 1 sll $s1, $s1, PIXEL_WIDTH_IN_SHIFTS sll $s1, $s1, WIDTH_IN_SHIFTS add $s2, $s2, $s1 add $t0, $zero, PIXEL_WIDTH # wee tweak sub $s2, $s2, $t0 addi $s0, $s0, -1 bne $s0, $zero, set_pixel_row set_pixel_exit: la $t1, SET_PIXEL_SAVES lw $ra, 0($t1) lw $s0, 4($t1) lw $s1, 8($t1) lw $s2, 12($t1) jr $ra .text # encoding of branch instructions uses # PC relative 2's complement offsets back: ori $10,$10,0x1 nop nop beq $15,$15, forward # 0x11ef0005 nop bne $14,$14, back # 0x15cefffa nop nop nop forward: andi $14,$14,0x1 # control_flow.asm # # The only control mechanism in MIPS is, effectively, a goto. # # This means that programmers are free to write so-called spaghetti code with # branches and jumps all throughout their programs. # # In this course, you should continue to think about your programs using # high level constructs like if statements, if-else, while loops and for loops. # # Below are “translations” of these concepts into assembly language. # # Note that it is common to invert the condition when translating to # assembly language. # # if (a == b) { # code 1 # } # code2 bne $8, $9, skip nop # code 1 skip: nop # code 2 # # if ( a == b) { # code 1 # } # else { # code 2 # } # code 3 bne $8,$9, skip # code 1 j done skip: # code 2 done: # code 3 # # while ( a != b ) { # code 1 # } # code 2 loop: beq $8, $9, done # code 1 j loop done: # code 2 .text # $a0 - address of string # $a1 - character to count # $v0 - number of times character is in string la $a0, str1 li $a1, 'i' jal count_char jal print_v0 la $a0, str2 li $a1, 'n' jal count_char jal print_v0 li $v0, 10 # system call for exit syscall # Exit! # $a0 - address of the string to find the length of # $a1 - character to count # $v0 - number of times character is in string # # $t0 - the current string character # $t1 - copy of the parameter $a0 to move through string count_char: # you code this jr $ra print_v0: or $a0,$zero,$v0 li $v0, 1 # specify Print Integer service syscall # print string length li $v0, 4 la $a0, newline syscall jr $ra .data str1: .asciiz "This is the first string" str2: .asciiz "And another one." str3: .asciiz "short" newline: .asciiz "\n" .text # $a0 - address of string # $a1 - character to count # $v0 - number of times character is in string la $a0, str1 li $a1, 'i' jal count_char jal print_v0 la $a0, str2 li $a1, 'n' jal count_char jal print_v0 li $v0, 10 # system call for exit syscall # Exit! # $a0 - address of the string to find the length of # $a1 - character to count # $v0 - number of times character is in string # # $t0 - the current string character # $t1 - copy of the parameter $a0 to move through string count_char: or $t1, $0, $a0 # copy of a0 into t1 li $v0, 0 lbu $t0, 0($t1) strlp: beq $t0, $0, strdone addiu $t1, $t1, 1 bne $t0, $a1, skip_a addiu $v0, $v0, 1 skip_a: lbu $t0, 0($t1) j strlp strdone: jr $ra print_v0: or $a0,$zero,$v0 li $v0, 1 # specify Print Integer service syscall # print string length li $v0, 4 la $a0, newline syscall jr $ra .data str1: .asciiz "This is the first string" str2: .asciiz "And another one." str3: .asciiz "short" newline: .asciiz "\n" # See here for details on encoding: # https://en.wikibooks.org/wiki/MIPS_Assembly/Instruction_Formats # .text li $8, 10 li $9, 20 li $10, 0 # addu is an R-type instruction # || 31..26 | 25..21 | 20..16 | 15..11 | 10..6 | 5..0 || # || opcode | rs | rt | rd | shift amount | function || addu $10, $8, $9 # 0x01095021 # | 0000 00 | 01 000 | 0 1001 | 0101 0 | 000 00 | 10 0001 | # | opcode | r8 | r9 | r10 | none | add unsigned | addu $31, $31, $31 # | 0000 00 | 11 111 | 1 1111 | 1111 1 | 000 00 | 10 0001 | # | 0000 | 0011 1111 1111 1111 1000 0010 0001 | # 0x03FFF821 add $10, $8, $9 # 0x01095020 # | 0000 00 | 01 000 | 0 1001 | 0101 0 | 000 00 | 10 0000 | sub $10, $8, $9 # 0x01095022 # | 0000 00 | 01 000 | 0 1001 | 0101 0 | 000 00 | 10 0010 | sll $8, $9, 15 # 0x000943C0 # An implementation of fibonacci # # NB: The slides also contain an implementation that is # similar, perhaps identical to this one, but Jason # wrote this example and Mike wrote the one in the slides # # Both based on this code: # # int fib (int n) { # int a; # int b; # # if (n<2) { # return 1; # } # n = n - 1; # a = fib(n); # n = n - 1; # b = fib(n) # # return a + b; # } # .text li $a0, 10 jal fib add $a0, $zero, $v0 li $v0, 1 syscall li $v0, 10 syscall # a0 - value to calculate fib of # v0 - fib(a0) # s0 - a copy of a0, that we save across jal # t0 - temp for comparison and computing sum # Stack: # # +------+ # | $ra | 12 # | $s0 | 8 # | a | 4 # | b | 0 # fib: addi $sp, $sp, -16 sw $s0, 8($sp) sw $ra, 12($sp) add $s0, $zero, $a0 # copy a0 to s0 li $v0, 1 # default return value is 1 li $t0, 2 # for a0 < 2, ie a0 == 0 || a0 == 1 blt $s0, $t0, fib_done # nothing to do addi $s0, $s0, -1 # add $a0, $zero, $s0 # call fib(n-1) jal fib sw $v0, 4($sp) # save result addi $s0, $s0, -1 # add $a0, $zero, $s0 # call fib (n-2) jal fib sw $v0, 0($sp) # save result # didn't need to load both of these # as we have the result of fib(n-2) # in v0, but a compiler might do this lw $v0, 0($sp) # a lw $t0, 4($sp) # b add $v0, $v0, $t0 # v0 = a + b fib_done: lw $s0, 8($sp) lw $ra, 12($sp) addiu $sp, $sp, 16 jr $ra # # An example of how the following code might be implemented in assembly # # main () { # int result = 0; # result = max3(10,17,22); # print result; # } # # int max3(int a, int b, int c) { # int retval = a; # if (b > retval) {
# retval = b;
# }
# if (c > retval) {
# retval = c;
# }
# return retval;
# }

.text
# note that the main function *is* called by
# some code inserted by the compiler to work
# with the operating system.

jal main
li $v0, 10 # system call for exit
syscall # Exit!

#
#
# stack frame:
# +——-+
# | $ra | 4
# | result| 0 <-sp # main: addi $sp, $sp, -8 sw $ra, 4($sp) # save return address sw $zero, 0($sp) # initialize result to 0 # parameters in $a0 to $a2 li $a0, 10 li $a1, 17 li $a2, 22 jal max3 # $v0 has the result, store it in our local sw $v0, 0($sp) # print integer service expects the integer to # print to be in $a0 lw $a0, 0($sp) li $v0, 1 syscall la $a0, newline li $v0, 4 syscall # no need to load 0($sp) as it is a local variable # who's value we don't care about when we return lw $ra, 4($sp) # restore return address addi $sp, $sp, 8 jr $ra # stack frame: # +-------+ # | $ra | 4 # | result| 0 <-sp # # parameters: # $a0 - a # $a1 - b # $a2 - c # # return value: # max of a, b, c in $v0 # # In this example we explicitly update the local variable # on the stack. A compiler or when writing this by hand # probably wouldn't bother, and instead just keep the # maximum value in a register the whole time. max3: addi $sp, $sp, -8 sw $ra, 4($sp) # save return address sw $a0, 0($sp) # intial guess for max is a lw $v0, 0($sp) # put retval local into $v0 for return lw $ra, 4($sp) # restore return address addi $sp, $sp, 8 jr $ra .data newline: .asciiz "\n" # # An example of how the following code might be implemented in assembly # # main () { # int result = 0; # result = max3(10,17,22); # print result; # } # # int max3(int a, int b, int c) { # int retval = a; # if (b > retval) {
# retval = b;
# }
# if (c > retval) {
# retval = c;
# }
# return retval;
# }

.text
# note that the main function *is* called by
# some code inserted by the compiler to work
# with the operating system.

jal main
li $v0, 10 # system call for exit
syscall # Exit!

#
#
# stack frame:
# +——-+
# | $ra | 4
# | result| 0 <-sp # main: addi $sp, $sp, -8 sw $ra, 4($sp) # save return address sw $zero, 0($sp) # initialize result to 0 # parameters in $a0 to $a2 li $a0, 10 li $a1, 17 li $a2, 22 jal max3 # $v0 has the result, store it in our local sw $v0, 0($sp) # print integer service expects the integer to # print to be in $a0 lw $a0, 0($sp) li $v0, 1 syscall la $a0, newline li $v0, 4 syscall # no need to load 0($sp) as it is a local variable # who's value we don't care about when we return lw $ra, 4($sp) # restore return address addi $sp, $sp, 8 jr $ra # stack frame: # | | # 0xFFFF000C +-------+ # 0xFFFF0008 | $ra | 4 # 0xFFFF0004 | result| 0 <-sp # # parameters: # $a0 - a # $a1 - b # $a2 - c # # $t0 - used for calculations # # return value: # max of a, b, c in $v0 # # In this example we explicitly update the local variable # on the stack. A compiler or when writing this by hand # probably wouldn't bother, and instead just keep the # maximum value in a register the whole time. max3: addi $sp, $sp, -8 sw $ra, 4($sp) # save return address sw $a0, 0($sp) # intial guess for max is a lw $t0, 0($sp) # $t0 is our current guess for max ble $a1, $t0, check_c # b >
or $t0, $zero, $a1
check_c:
ble $a2, $t0, done
# c >
or $t0, $zero, $a2
done:
sw $t0, 0($sp)

lw $v0, 0($sp) # put retval local into $v0 for return

lw $ra, 4($sp) # restore return address
addi $sp, $sp, 8
jr $ra

.data
newline:
.asciiz “\n”
#
# An introduction to interrupts.
# This code contains the minimum code to
# respond to an interrupt from the external keyboard tool.
#
# More detail in the labs and lecture next week.
#
.text
main:
# MARS starts with interrupts enabled, but we
# must specifically enable interrupts from the
# keyboard device:
la $t0, 0xffff0000 # control register for MMIO Simulator “Receiver”
lb $t1, 0($t0)
ori $t1, $t1, 0x02 # Set bit 1 to enable Receiver interrupts (i.e., keyboard)
sb $t1, 0($t0)

li $at, 0x00000000
loop:
addiu $at, $at, 1
b loop
# NB:
# One only has $k0 and $k1 to use in the
# exception handler.
#
# One *cannot* use the stack to save registers
# If more than $k0 and $k1 are needed, then space
# in .kdata must be allocated.
#
# The easiest way to do this is static space for
# specific registers, but that makes the
# exception handler non-rentrant.
#
# Psuedo instructions cannot be used
# unless you first save $at (good question for a midterm, why?)
#
# We are saving $at in a static location which makes this
# handler non-rentrant.
#
.kdata
save_at:
.word 0x00

# The exception handler must be at this location
.ktext 0x80000180

csc230_ehandler:
# save $at so we can use pseudo-instructions
or $k0, $zero, $at
la $k1, save_at
sw $k0, 0($k1)

# We can end up here for three reasons:
# A trap, an exception or an interrupt
# In this class we will only deal with interrupts.
# The reason we are here is in the cause register in coproc0 $13
mfc0 $k0, $13
andi $k1, $k0, 0x7C # 7C: 01111100 –> mask to select bits 2 to 6 which is the exccode
# ExcCode is 0 for interrupts
srl $k1, $k1, 2 # shift to make comparsion easier
beq $k1, $zero, csc230_is_interrupt
# If we get here it is either an exception or a trap
# We aren’t going to handle either.
j csc230_exit_ehandler

csc230_is_interrupt:
nop

csc230_exit_ehandler:
# restore $at
la $k1, save_at
lw $at, 0($k1)
eret

.text
start:
nor $12, $21, $7
srl $3, $4, 5
addi $8, $0, 250
beq $28, $5, asgard
nop
nop
asgard:
nop
beq $0, $0, start
.data

nums:
.word 1, 3, 5, -11, 22, 33, -4, 5, 0

.text
li $10, 0xdeadbeef

la $11, nums
lw $12, 16($11)

.text

label_A:
addi $8, $0, 25
beq $8, $9, label_C
srl $8, $8, 5
nop

label_B:
addi $8, $8, -21
andi $8, $8, 0x0abe
beq $0, $0, label_A

label_C:
nop
beq $9, $8, label_A
nop.data

bob:
.word 212

connie:
.word 40122

.text
# Store the sum of integer
# at ‘bob’ and integer at
# ‘connie’ into register
# $12 — and without using
# bob or connie directly
# in a ‘lw’ instruction
# (ie must use register and
# an offset of zero).
.data

location1: .space 4
location2: .space 4

.text
la $8, location1
addi $9, $0, 0xcafef00d # Same as decimal -889262067
sw $9, 0($8)

la $8, location2

addi $9, $0, 0xca
sb $9, 0($8)
addi $8, $8, 1

addi $9, $0, 0xfe
sb $9, 0($8)
addi $8, $8, 1

addi $9, $0, 0xf0
sb $9, 0($8)
addi $8, $8, 1

addi $9, $0, 0x0d
sb $9, 0($8)

.data

location1: .space 4
location2: .space 4
locationA: .asciiz “meow! moo!”

.text
la $8, location1
addi $9, $0, 0xcafef00d # Same as decimal -889262067
sw $9, 0($8)

la $8, location2

addi $9, $0, 0xca
sb $9, 0($8)
addi $8, $8, 1

addi $9, $0, 0xfe
sb $9, 0($8)
addi $8, $8, 1

addi $9, $0, 0xf0
sb $9, 0($8)
addi $8, $8, 1

addi $9, $0, 0x0d
sb $9, 0($8)

.data

stringA: .asciiz “We’re off to see the wizard,”
stringB: .asciiz “the wonderful wizard of OZ!”
stringC: .asciiz “I’ll be back…”
stringD: .asciiz “Doh!”

# Given the string address loaded in $8,
# find the address of the null value that
# ends the string, and leave this in $10

.text
la $8, stringB

loop_start:
lb $9, 0($8)
beq $9, $0, finish
addi $8, $8, 1
beq $0, $0, loop_start

finish:
add $10, $0, $8

# At this point, the address of the null that
# terminates the string loaded in line 13
# must be stored in $10.data

stringA: .asciiz “We’re off to see the wizard,”
stringB: .asciiz “the wonderful wizard of OZ!”
stringC: .asciiz “I’ll be back…”
stringD: .asciiz “Doh!”

string_space:
.asciiz “XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”

# Given the string address loaded in $8,
# find the length of the string and store
# that length is $10

.text
la $8, stringD
add $10, $0, $0

loop_start:
lb $9, 0($8)
beq $9, $0, finish
addi $8, $8, 1
addi $10, $10, 1
beq $0, $0, loop_start

finish:
# Nothing more is needed

# At this point length of the string
# is stored in $9
.data

stringA: .asciiz “We’re off to see the wizard,”
stringB: .asciiz “the wonderful wizard of OZ!”
stringC: .asciiz “I’ll be back…”
stringD: .asciiz “Doh!”

string_space:
.space 100

.text
la $a0, stringD
jal string_len
beq $0, $0, finish

string_len:
add $v0, $zero, $zero
loop_start:
lb $t0, 0($a0)
beq $t0, $zero, return_from_string_len
addi $a0, $a0, 1
addi $v0, $v0, 1
beq $zero, $zero, loop_start
return_from_string_len:
jr $ra

finish:
# Nothing more is needed

# At this point length of the string
# is stored in $v0 which is the same register as $2

# Let’s preserve this in $s0
add $s0, $zero, $v0

li $v0, 10
syscall

.data

stringA: .asciiz “abcdefg”
stringB: .asciiz “1234556”
stringC: .asciiz “abc”
stringD: .asciiz “1234567890”

.text
# If both strings have the same length,
# then 1 is stored in $12,
# otherwise 0 is stored in $12

la $8, stringC # string 1
la $9, stringA # string 2

loop_start:
lb $10, 0($8)
lb $11, 0($9)

beq $10, $0, check_string_2_for_null
beq $11, $0, same_length_fail # If we get here, then string 2 is longer!
addi $8, $8, 1
addi $9, $9, 1
beq $0, $0, loop_start

check_string_2_for_null:
bne $11, $0, same_length_fail # if string 2 is not null here, then string 1 is longer
addi $12, $0, 1
beq $0, $0, end_it_all

same_length_fail:
add $12, $0, $0

end_it_all:
# Nothing more is needed

# At this point the value in $12 indicates
# whether or not the strings have the same
# length (0 == no, 1 == yes)

li $2, 10
syscall.text
addi $s0, $zero, 5
loop:
beq $s0, $zero, finish

################
# Display dashes

la $t0, 0xffff0011
la $t1, 0xffff0010

addi $t2, $zero, 0x40
addi $t3, $zero, 0x40

sb $t2, 0($t0)
sb $t3, 0($t1)

############################
# Sleep for 400 milliseconds

jal delay_400_msec

################
# Display blanks

la $t0, 0xffff0011
la $t1, 0xffff0010

sb $zero, 0($t0)
sb $zero, 0($t1)

############################
# Sleep for 400 milliseconds

jal delay_400_msec

################
# Display digits

la $t0, 0xffff0011
la $t1, 0xffff0010

addi $t2, $zero, 0x5b
addi $t3, $zero, 0x06

sb $t2, 0($t0)
sb $t3, 0($t1)

############################
# Sleep for 400 milliseconds

jal delay_400_msec

################
# Display blanks

la $t0, 0xffff0011
la $t1, 0xffff0010

sb $zero, 0($t0)
sb $zero, 0($t1)

############################
# Sleep for 400 milliseconds

jal delay_400_msec

addi $s0, $s0, -1
beq $zero, $zero, loop

finish:
addi $v0, $zero, 10
syscall

delay_400_msec:
addi $sp, $sp -4
sw $ra, 0($sp)

addi $a0, $zero, 400
addi $v0, $zero, 32
syscall

lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
.text
addi $s0, $zero, 5
loop:
beq $s0, $zero, finish

jal display_dashes
jal delay_400_msec

jal display_blanks
jal delay_400_msec

jal display_digits_21
jal delay_400_msec

jal display_blanks
jal delay_400_msec

addi $s0, $s0, -1

beq $zero, $zero, loop

finish:
addi $v0, $zero, 10
syscall

# Use only $s0 – $s7 for computation in
# this procedure.

display_dashes:
jr $ra

# Use only $s0 – $s7 for computation in
# this procedure.

display_blanks:
jr $ra

# Use only $s0 – $s7 for computation in
# this procedure.

display_digits_21:
jr $ra

# Nothing needs to be done for the
# delay_400_msec procedure.

delay_400_msec:
addi $sp, $sp -4
sw $ra, 0($sp)

addi $a0, $zero, 400
addi $v0, $zero, 32
syscall

lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
.data

seven_segment:
.byte 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x5f, 0x7c, 0x39, 0x5e, 0x79, 0x71

.text
addi $s0, $zero, 16

la $s1, 0xffff0010
la $s2, 0xffff0011
la $s3, seven_segment

loop:
addi $s0, $s0, -1

# Load pattern for the digit
add $t0, $s0, $s3
lb $t1, 0($t0)

###############################################
# Display the digit on both seven-segment units
sb $t1, 0($s1)
sb $t1, 0($s2)

#############################
# Sleep for 1000 milliseconds

jal delay_1000_msec

bne $s0, $zero, loop

finish:
addi $v0, $zero, 10
syscall

delay_1000_msec:
addi $sp, $sp -4
sw $ra, 0($sp)

addi $a0, $zero, 1000
addi $v0, $zero, 32
syscall

lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
.data

seven_segment:
.byte 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x5f, 0x7c, 0x39, 0x5e, 0x79, 0x71

.text
addi $a0, $zero, 0xe
addi $a1, $zero, 1
jal display_hex_digit

addi $a0, $zero, 0xa
addi $a1, $zero, 0
jal display_hex_digit

finish:
addi $v0, $zero, 10
syscall

# $a0: hex digit to be displayed
# $a1: 0 == right display; 1 == left display

display_hex_digit:
jr $ra
.data

seven_segment:
.byte 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x5f, 0x7c, 0x39, 0x5e, 0x79, 0x71

.text
addi $a0, $zero, 0x2b
jal count_up_with_display
jal display_dashes

finish:
addi $v0, $zero, 10
syscall

# $a0: Maximum counter value

count_up_with_display:
jr $ra

# $a0: hex digit to be displayed
# $a1: 0 == right display; 1 == left display

display_hex_digit:
jr $ra

delay_400_msec:
addi $sp, $sp -4
sw $ra, 0($sp)

addi $a0, $zero, 400
addi $v0, $zero, 32
syscall

lw $ra, 0($sp)
add $sp, $sp, 4
jr $ra

display_dashes:
jr $ra

.data

S1: .asciiz “abc def”
S2: .asciiz “ghi jkl”
SPACE: .asciiz ” ”
NL: .asciiz “\n”

YEAR: .word 2020

.text
main:
la $a0, S1
addi $v0, $zero, 4
syscall

la $a0, SPACE
addi $v0, $zero, 4
syscall

la $a0, S2
addi $v0, $zero, 4
syscall

la $a0, SPACE
addi $v0, $zero, 4
syscall

la $s0, YEAR
lw $a0, 0($s0)
addi $v0, $zero, 1
syscall

la $a0, NL
addi $v0, $zero, 4
syscall

addi $v0, $zero, 10
syscall
.data

S1: .asciiz “In what year were you born? ”
S2: .asciiz “What year is it now? ”
S3: .asciiz “You will turn ”
S4: .asciiz ” years old this year.\n”
SPACE: .asciiz ” ”
NL: .asciiz “\n”

.text
main:
la $a0, S4
addi $v0, $zero, 4
syscall

addi $v0, $zero, 10
syscall
.text
main:
# Must enable the keyboard device (i.e., in the “MMIO” simulator) to
# generate interrupts. 0xffff0000 is the location in kernel memory
# mapped to the control register of the keybaord.

la $s0, 0xffff0000 # control register for MMIO Simulator “Receiver”
lb $s1, 0($s0)
ori $s1, $s1, 0x02 # Set bit 1 to enable “Receiver” interrupts (i.e., keyboard)
sb $s1, 0($s0)

# We’ll keep incrementing $t5 every time through the loop below.
# $t6 will be incremented each time there is a keyboard interrupt.
# $t7 will hold the ASCII code of the most-recently pressed key.
# (By “key”, we mean key pressed in the “Keyboard and Display MMIO Simulator”.)

add $t5, $zero, $zero
add $t6, $zero, $zero

forever_loop:
addi $t5, $t5, 1
beq $zero, $zero, forever_loop

.kdata

# No data in the kernel-data section (at present)

.ktext 0x80000180 # Required address in kernel space for exception dispatch
__kernel_entry:
mfc0 $k0, $13 # $13 is the “cause” register in Coproc0
andi $k1, $k0, 0x7c # bits 2 to 6 are the ExcCode field (0 for interrupts)
srl $k1, $k1, 2 # shift ExcCode bits for easier comparison
beq $zero, $k1, __is_interrupt

__is_exception:
# Something of a placeholder…
# … just in case we can’t escape the need for handling some exceptions.
beq $zero, $zero, __exit_exception

__is_interrupt:
andi $k1, $k0, 0x0100 # examine bit 8
bne $k1, $zero, __is_keyboard_interrupt # if bit 8 set, then we have a keyboard interrupt.

beq $zero, $zero, __exit_exception # otherwise, we return exit kernel

__is_keyboard_interrupt:
addi $t6, $t6, 1
la $k0, 0xffff0004
lw $t7, 0($k0)
# Note: We could also take the value obtained from the “lw:
# and store it someplace in data memory. However, to keep
# things simple, we’re using $t7 immediately above.

beq $zero, $zero, __exit_exception # Kept here in case we add more handlers.

__exit_exception:
eret

.data
NUM_KEYBOARD_EVENTS:
.word 0
LAST_KEYBOARD_EVENT:
.word 0

.text
main:
# Must enable the keyboard device (i.e., in the “MMIO” simulator) to
# generate interrupts. 0xffff0000 is the location in kernel memory
# mapped to the control register of the keybaord.

la $s0, 0xffff0000 # control register for MMIO Simulator “Receiver”
lb $s1, 0($s0)
ori $s1, $s1, 0x02 # Set bit 1 to enable “Receiver” interrupts (i.e., keyboard)
sb $s1, 0($s0)

# We’ll keep incrementing $t5 every time through the loop below.
# $t6 will be incremented each time there is a keyboard interrupt.
# $t7 will hold the ASCII code of the most-recently pressed key.
# (By “key”, we mean key pressed in the “Keyboard and Display MMIO Simulator”.)

add $t5, $zero, $zero
add $t6, $zero, $zero

forever_loop:
addi $t5, $t5, 1
beq $zero, $zero, forever_loop

.kdata

# No data in the kernel-data section (at present)

.ktext 0x80000180 # Required address in kernel space for exception dispatch
__kernel_entry:
mfc0 $k0, $13 # $13 is the “cause” register in Coproc0
andi $k1, $k0, 0x7c # bits 2 to 6 are the ExcCode field (0 for interrupts)
srl $k1, $k1, 2 # shift ExcCode bits for easier comparison
beq $zero, $k1, __is_interrupt

__is_exception:
# Something of a placeholder…
# … just in case we can’t escape the need for handling some exceptions.
beq $zero, $zero, __exit_exception

__is_interrupt:
andi $k1, $k0, 0x0100 # examine bit 8
bne $k1, $zero, __is_keyboard_interrupt # if bit 8 set, then we have a keyboard interrupt.

beq $zero, $zero, __exit_exception # otherwise, we return exit kernel

__is_keyboard_interrupt:
addi $t6, $t6, 1
la $k0, 0xffff0004
lw $t7, 0($k0)
# Note: We could also take the value obtained from the “lw:
# and store it someplace in data memory. However, to keep
# things simple, we’re using $t7 immediately above.

beq $zero, $zero, __exit_exception # Kept here in case we add more handlers.

__exit_exception:
eret

# This code assumes the use of the “Bitmap Display” tool.
#
# Tool settings must be:
# Unit Width in Pixels: 32
# Unit Height in Pixels: 32
# Display Width in Pixels: 512
# Display Height in Pixels: 512
# Based Address for display: 0x10010000 (static data)
#
# In effect, this produces a bitmap display of 16×16 pixels.

.include “bitmap-routines.asm”

.data
TELL_TALE:
.word 0x12345678 0x9abcdef0 # Helps us visually detect where our part starts in .data section

.globl main
.text
main:
addi $a0, $zero, 0
addi $a1, $zero, 0
addi $a2, $zero, 0x00ffff00
jal set_pixel

addi $a0, $zero, 15
addi $a1, $zero, 15
addi $a2, $zero, 0x00ff0000
jal set_pixel

addi $a0, $zero, 7
addi $a1, $zero, 7
addi $a2, $zero, 0x00ffa500
jal set_pixel

addi $a0, $zero, 8
addi $a1, $zero, 8
addi $a2, $zero, 0x00aaaaaa
jal set_pixel

addi $v0, $zero, 10
syscall
.text
li $8, 0xDEADBEEF
li $9, -1
li $10, 1234

li $8, 10
li $9, 20
addu $10, $8, $9

li $8, -1
li $9, -2
addu $10, $8, $9

li $v0, 10 # system call for exit
syscall
.text

li $8, 10
li $9, 10
li $10,10
li $11,10

# there are a variety of ways to
# accomplish the same task.
# Here are 4 ways to set a register
# value to 0.
#
addiu $8, $0, 0 # set $8 to 0
and $10,$0,$0
sll $11,$0,0
li $9, 0

# calculate the sum of the integers 1 to 5
# $8 is our counter
# $9 is the sum
li $9, 0

addiu $8, $8, 1
addu $9, $9, $8
addiu $8, $8, 1
addu $9, $9, $8
addiu $8, $8, 1
addu $9, $9, $8
addiu $8, $8, 1
addu $9, $9, $8
addiu $8, $8, 1
addu $9, $9, $8

or $a0,$9, $10
li $v0, 1 # specify Print Integer service
syscall

li $v0, 10 # system call for exit
syscall # Exit!

# lecture_ex_02.asm

.text

li $8, 22
li $9, 21
li $10, 0

bne $8,$9, skip # NB: On a real processor, or if you enable “delayed branching” in MARS, this code is wrong.
li $10, 1

skip:
li $v0, 10 # system call for exit
syscall # Exit!

.text
#
# See if there are at least 2 consecutive 1 bits in $8
#
# $8 – word to examine
# $9 – set to 1 if consecutive 1 bits in $8, 0 otherwise
# $10 – flag — 1 if previous bit was 1, 0 otherwise
# $11 – bit counter
# $12 – current bit value
li $8,0×8802022 # | 1000 0010
li $9,0
li $10,0
li $11,32
li $12,0
# value = 0x8802020
# two_consecutive = false
# previous_is_one = false
# count = 32
# current_bit = 0
#
# while (count != 0) {
# current_bit = value & 1
# value = value >> 1
# if (current_bit == 0) {
# previous_is_one = false
# }
# else {
# if (previous_is_one) {
# two_consecutive = true
# break
# }
# previous_is_one = true
# }
# count = count – 1
#}
#

# 1111
# 0001 and
# —-
# 0001

# $8 – word to examine
# $9 – set to 1 if consecutive 1 bits in $8, 0 otherwise
# $10 – flag — 1 if previous bit was 1, 0 otherwise
# $11 – bit counter
# $12 – current bit value
loop:
beq $11, $0, done # is the loop finished?
andi $12, $8, 1 # put the current bit in $12
srl $8, $8, 1 # shift to the right
beq $12, $0, zero # is the current bit 0?
bne $10, $0, two_consecutive # if the flag is set and we have a 1 bit, we are done, found 2 in a row
li $10, 1 # if we get here, the previous bit wasn’t a 1, set the flag for current bit
j loop_end
zero:
li $10, 0 # clear the flag, 0 bit
loop_end:
subiu $11, $11, 1 # update loop counter
j loop # restart the loop
two_consecutive:
li $9, 1 # found 2 consecutive 1 bits
done:
nop
nop

.text
la $10,data1
la $11,data2

lw $15,0($10)
lw $16,0($11)
nop
nop
la $12,data3
lbu $17,0($12)
nop
nop
.data

data1:
.word 0xDEADBEEF
data2:
.word 0xAACEAACE
data3:
.byte 1,2,3,4,5
.text

# $15 – pointer to current character in string
# $10 – string length
# $11 – current character

la $15, str1 # $15 points to the string
li $10, 0 # $10 will be the length of the string

lbu $11, 0($15) # get the first character into $11
loop:
beq $11, $0, done # if the character is a 0, we are at end of the string
addiu $10, $10, 1 # increment the count
addiu $15, $15, 1 # move the pointer to the next character
lbu $11, 0($15) # get the next character
j loop

done:
or $a0,$0,$10
li $v0, 1 # specify Print Integer service
syscall # print string length
li $v0, 10 # system call for exit
syscall # Exit!

.data
ex1:
.byte 0x01, 0x02, 0x03, 0x04
str1:
.asciiz “This is the first string”
str2:
.asciiz “And another one.”
str3:
.asciiz “short”
str4:
.asciiz “”
.text
nop
jal print_it
nop
nop
li $v0, 10 # system call for exit
syscall # Exit!

print_it:
addi $sp, $sp, -4
sw $ra, 0($sp)

la $a0, hello
jal print_a0
la $a0, world
jal print_a0
nop

lw $ra, 0($sp)
addi $sp, $sp, 4
jr $31

print_a0:
li $v0, 4
syscall

jr $ra

.data
hello:
.asciiz “Hello ”
world:
.asciiz “World\n”
.text

# $a0 – address of string

la $a0, str1
jal strlen

or $a0,$0,$v0
li $v0, 1 # specify Print Integer service
syscall # print string length

la $a0, str2
jal strlen

or $a0,$0,$v0
li $v0, 1 # specify Print Integer service
syscall # print string length

li $v0, 10 # system call for exit
syscall # Exit!

# $a0 – address of the string to find the length of
# $v0 – length in bytes of the string
#
# $t0 – the current string character
# $t1 – copy of the parameter $a0 to move through string

strlen:
or $t1, $0, $a0 # copy of a0 into t1
li $v0, 0
lbu $t0, 0($t1)
strlp:
beq $t0, $0, strdone
addiu $v0, $v0, 1
addiu $t1, $t1, 1
lbu $t0, 0($t1)
j strlp
strdone:
jr $ra

.data
str1:
.asciiz “This is the first string”
str2:
.asciiz “And another one.”
str3:
.asciiz “short”.text

# $a0 – address of string
# $v0 – returned length of string
# $v0 – selects which system call
la $a0, str1
jal strlen # goes to strlen label and stores “return address” in $ra
jal print_v0

la $a0, str2
jal strlen
jal print_v0

li $v0, 10 # system call for exit
syscall # Exit!

# $a0 – address of the string to find the length of
# $v0 – length in bytes of the string
#
# $t0 – the current string character
# $t1 – copy of the parameter $a0 to move through string

strlen:
or $t1, $0, $a0 # copy of a0 into t1
li $v0, 0
lbu $t0, 0($t1)
strlp:
beq $t0, $0, strdone
addiu $v0, $v0, 1
addiu $t1, $t1, 1
lbu $t0, 0($t1)
j strlp
strdone:
jr $ra

print_v0:
or $a0,$zero,$v0
li $v0, 1 # specify Print Integer service
syscall # print string length

li $v0, 4
la $a0, newline
syscall

jr $ra

.data
str1:
.asciiz “This is the first string”
str2:
.asciiz “And another one.”
str3:
.asciiz “short”
newline:
.asciiz “\n”