Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

File to edit sprintf ~~~~~~~~~~~~~~~~~ #sprintf! #$a0 has the pointer to the buf

ID: 3831906 • Letter: F

Question

File to edit

sprintf

~~~~~~~~~~~~~~~~~

#sprintf!
#$a0 has the pointer to the buffer to be printed to
#$a1 has the pointer to the format string
#$a2 and $a3 have (possibly) the first two substitutions for the format string
#the rest are on the stack
#return the number of characters (ommitting the trailing '') put in the buffer

.text

sprintf:

   jr   $ra       #this sprintf implementation rocks!

SUPPLEMENTARY CODE

spf-string

~~~~~~~~~~~~~~

######################################################################
# spf-main.s
#
# This is the main function that tests the sprintf function

# The "data" segment is a static memory area where we can
# allocate and initialize memory for our program to use.
# This is separate from the stack or the heap, and the allocation
# cannot be changed once the program starts. The program can
# write data to this area, though.
   .data
  
# Note that the directives in this section will not be
# translated into machine language. They are instructions
# to the assembler, linker, and loader to set aside (and
# initialize) space in the static memory area of the program.
# The labels work like pointers-- by the time the code is
# run, they will be replaced with appropriate addresses.

# For this program, we will allocate a buffer to hold the
# result of your sprintf function. The asciiz blocks will
# be initialized with null-terminated ASCII strings.

buffer:   .space   2000           # 2000 bytes of empty space
                   # starting at address 'buffer'
  
format:   .asciiz "string: %5.5s %5.5s "# null-terminated string of
                   # ascii bytes. Note that the
                   # counts as one byte: a newline
                   # character.
str1:   .asciiz "abcdefg"       # null-terminated string at
                   # address 'str1'
str2: .asciiz "abc"            # null-terminated string at
# address 'str2'
chrs:   .asciiz " characters: "   # null-terminated string at
                   # address 'chrs'

# The "text" of the program is the assembly code that will
# be run. This directive marks the beginning of our program's
# text segment.

   .text
  
# The sprintf procedure (really just a block that starts with the
# label 'sprintf') will be declared later. This is like a function
# prototype in C.

   .globl sprintf
      
# The special label called "__start" marks the start point
# of execution. Later, the "done" pseudo-instruction will make
# the program terminate properly.  

main:
   addi   $sp,$sp,-20   # reserve stack space

   # $v0 = sprintf(buffer, format, str1, str2)
  
   la   $a0,buffer   # arg 0 <- buffer
   la   $a1,format   # arg 1 <- format
   la   $a2,str1   # arg 2 <- str1
   la    $a3,str2 # arg 3 <- str2  
  
   sw   $ra,16($sp)   # save return address
   jal   sprintf       # $v0 = sprintf(...)

   # print the return value from sprintf using
   # putint()

   add   $a0,$v0,$0   # $a0 <- $v0
   jal   putint       # putint($a0)

   ## output the string 'chrs' then 'buffer' (which
   ## holds the output of sprintf)

    li    $v0, 4  
   la    $a0, chrs
   syscall
   #puts   chrs       # output string chrs
  
   li   $v0, 4
   la   $a0, buffer
   syscall
   #puts   buffer       # output string buffer
  
   addi   $sp,$sp,20   # restore stack
   li    $v0, 10       # terminate program
   syscall

# putint writes the number in $a0 to the console
# in decimal. It uses the special command
# putc to do the output.
  
# Note that putint, which is recursive, uses an abbreviated
# stack. putint was written very carefully to make sure it
# did not disturb the stack of any other functions. Fortunately,
# putint only calls itself and putc, so it is easy to prove
# that the optimization is safe. Still, we do not recommend
# taking shortcuts like the ones used here.

# HINT:   You should read and understand the body of putint,
# because you will be doing some similar conversions
# in your own code.
  
putint:   addi   $sp,$sp,-8   # get 2 words of stack
   sw   $ra,0($sp)   # store return address
  
   # The number is printed as follows:
   # It is successively divided by the base (10) and the
   # reminders are printed in the reverse order they were found
   # using recursion.

   remu   $t0,$a0,10   # $t0 <- $a0 % 10
   addi   $t0,$t0,'0'   # $t0 += '0' ($t0 is now a digit character)
   divu   $a0,$a0,10   # $a0 /= 10
   beqz   $a0,onedig   # if( $a0 != 0 ) {
   sw   $t0,4($sp)   # save $t0 on our stack
   jal   putint       # putint() (putint will deliberately use and modify $a0)
   lw   $t0,4($sp)   # restore $t0
   # }
onedig:   move   $a0, $t0
   li    $v0, 11
   syscall           # putc #$t0
   #putc   $t0       # output the digit character $t0
   lw   $ra,0($sp)   # restore return address
   addi   $sp,$sp, 8   # restore stack
   jr   $ra       # return

spf-main

~~~~~~~~~~~~~~~

######################################################################
# spf-main.s
#
# This is the main function that tests the sprintf function

# The "data" segment is a static memory area where we can
# allocate and initialize memory for our program to use.
# This is separate from the stack or the heap, and the allocation
# cannot be changed once the program starts. The program can
# write data to this area, though.
   .data
  
# Note that the directives in this section will not be
# translated into machine language. They are instructions
# to the assembler, linker, and loader to set aside (and
# initialize) space in the static memory area of the program.
# The labels work like pointers-- by the time the code is
# run, they will be replaced with appropriate addresses.

# For this program, we will allocate a buffer to hold the
# result of your sprintf function. The asciiz blocks will
# be initialized with null-terminated ASCII strings.

buffer:   .space   20000           # 2000 bytes of empty space
                   # starting at address 'buffer'
  
format:   .asciiz "string: %s, unsigned dec: %u, hex: 0x%x, oct: 0%o, dec: %d "
                   # null-terminated string of
                   # ascii bytes. Note that the
                   # counts as one byte: a newline
                   # character.
str:   .asciiz "thirty-nine"       # null-terminated string at
                   # address 'str'
chrs:   .asciiz " characters: "   # null-terminated string at
                   # address 'chrs'

# The "text" of the program is the assembly code that will
# be run. This directive marks the beginning of our program's
# text segment.

   .text
  
# The sprintf procedure (really just a block that starts with the
# label 'sprintf') will be declared later. This is like a function
# prototype in C.

   .globl sprintf
      
# The special label called "__start" marks the start point
# of execution. Later, the "done" pseudo-instruction will make
# the program terminate properly.  

main:
   addi   $sp,$sp,-32   # reserve stack space

   # $v0 = sprintf(buffer, format, str, 255, 255, 250, -255)
  
   la   $a0,buffer   # arg 0 <- buffer
   la   $a1,format   # arg 1 <- format
   la   $a2,str       # arg 2 <- str
  
   addi   $a3,$0,255   # arg 3 <- 255
   sw   $a3,16($sp)   # arg 4 <- 255
  
   addi   $t0,$0,250
   sw   $t0,20($sp)   # arg 5 <- 250

addi $t0,$0,-255
sw $t0,24($sp) # arg 6 <- -255

   sw   $ra,28($sp)   # save return address
   jal   sprintf       # $v0 = sprintf(...)

   # print the return value from sprintf using
   # putint()
   add   $a0,$v0,$0   # $a0 <- $v0
   jal   putint       # putint($a0)

   ## output the string 'chrs' then 'buffer' (which
   ## holds the output of sprintf)
    li    $v0, 4  
   la    $a0, chrs
   syscall
   #puts   chrs       # output string chrs
  
   li   $v0, 4
   la   $a0, buffer
   syscall
   #puts   buffer       # output string buffer
  
   addi   $sp,$sp,32   # restore stack
   li    $v0, 10       # terminate program
   syscall

# putint writes the number in $a0 to the console
# in decimal. It uses the special command
# putc to do the output.
  
# Note that putint, which is recursive, uses an abbreviated
# stack. putint was written very carefully to make sure it
# did not disturb the stack of any other functions. Fortunately,
# putint only calls itself and putc, so it is easy to prove
# that the optimization is safe. Still, we do not recommend
# taking shortcuts like the ones used here.

# HINT:   You should read and understand the body of putint,
# because you will be doing some similar conversions
# in your own code.
  
putint:   addi   $sp,$sp,-8   # get 2 words of stack
   sw   $ra,0($sp)   # store return address
  
   # The number is printed as follows:
   # It is successively divided by the base (10) and the
   # reminders are printed in the reverse order they were found
   # using recursion.

   remu   $t0,$a0,10   # $t0 <- $a0 % 10
   addi   $t0,$t0,'0'   # $t0 += '0' ($t0 is now a digit character)
   divu   $a0,$a0,10   # $a0 /= 10
   beqz   $a0,onedig   # if( $a0 != 0 ) {
   sw   $t0,4($sp)   # save $t0 on our stack
   jal   putint       # putint() (putint will deliberately use and modify $a0)
   lw   $t0,4($sp)   # restore $t0
   # }
onedig:   move   $a0, $t0
   li    $v0, 11
   syscall           # putc #$t0
   #putc   $t0       # output the digit character $t0
   lw   $ra,0($sp)   # restore return address
   addi   $sp,$sp, 8   # restore stack
   jr   $ra       # return

spf-decimal

~~~~~~~~~~~~~~

######################################################################
# spf-main.s
#
# This is the main function that tests the sprintf function

# The "data" segment is a static memory area where we can
# allocate and initialize memory for our program to use.
# This is separate from the stack or the heap, and the allocation
# cannot be changed once the program starts. The program can
# write data to this area, though.
   .data
  
# Note that the directives in this section will not be
# translated into machine language. They are instructions
# to the assembler, linker, and loader to set aside (and
# initialize) space in the static memory area of the program.
# The labels work like pointers-- by the time the code is
# run, they will be replaced with appropriate addresses.

# For this program, we will allocate a buffer to hold the
# result of your sprintf function. The asciiz blocks will
# be initialized with null-terminated ASCII strings.

buffer:   .space   2000           # 2000 bytes of empty space
                   # starting at address 'buffer'
  
format:   .asciiz "string: |%-5d|%-5d|%5d|%5.5d|%+d|%.5d "
                   # null-terminated string of
                   # ascii bytes. Note that the
                   # counts as one byte: a newline
                   # character.
chrs:   .asciiz " characters: "   # null-terminated string at
                   # address 'chrs'

# The "text" of the program is the assembly code that will
# be run. This directive marks the beginning of our program's
# text segment.

   .text
  
# The sprintf procedure (really just a block that starts with the
# label 'sprintf') will be declared later. This is like a function
# prototype in C.

   .globl sprintf
      
# The special label called "__start" marks the start point
# of execution. Later, the "done" pseudo-instruction will make
# the program terminate properly.  

main:
   addi   $sp,$sp,-36   # reserve stack space

   # $v0 = sprintf(buffer, format, 1, 2, 3, 4, 5, 6)
  
   la   $a0,buffer   # arg 0 <- buffer
   la   $a1,format   # arg 1 <- format
   addi   $a2,$0,1   # arg 2 <- 1
   addi   $a3,$0,2   # arg 3 <- 2
   addi $t0,$0,3  
   sw   $a3,16($sp)   # arg 4 <- 3
  
   addi   $t0,$0,4
   sw   $t0,20($sp)   # arg 5 <- 4 ('o', as a character)
  
   addi   $t0,$0, 5
   sw   $t0,24($sp)   # arg 6 <- 5

   addi $t0,$0, 6
sw $t0,28($sp) # arg 7 <- 6

   sw   $ra,32($sp)   # save return address
   jal   sprintf       # $v0 = sprintf(...)

   # print the return value from sprintf using
   # putint()

   add   $a0,$v0,$0   # $a0 <- $v0
   jal   putint       # putint($a0)

   ## output the string 'chrs' then 'buffer' (which
   ## holds the output of sprintf)

    li    $v0, 4  
   la    $a0, chrs
   syscall
   #puts   chrs       # output string chrs
  
   li   $v0, 4
   la   $a0, buffer
   syscall
   #puts   buffer       # output string buffer
  
   addi   $sp,$sp,36   # restore stack
   li    $v0, 10       # terminate program
   syscall

# putint writes the number in $a0 to the console
# in decimal. It uses the special command
# putc to do the output.
  
# Note that putint, which is recursive, uses an abbreviated
# stack. putint was written very carefully to make sure it
# did not disturb the stack of any other functions. Fortunately,
# putint only calls itself and putc, so it is easy to prove
# that the optimization is safe. Still, we do not recommend
# taking shortcuts like the ones used here.

# HINT:   You should read and understand the body of putint,
# because you will be doing some similar conversions
# in your own code.
  
putint:   addi   $sp,$sp,-8   # get 2 words of stack
   sw   $ra,0($sp)   # store return address
  
   # The number is printed as follows:
   # It is successively divided by the base (10) and the
   # reminders are printed in the reverse order they were found
   # using recursion.

   remu   $t0,$a0,10   # $t0 <- $a0 % 10
   addi   $t0,$t0,'0'   # $t0 += '0' ($t0 is now a digit character)
   divu   $a0,$a0,10   # $a0 /= 10
   beqz   $a0,onedig   # if( $a0 != 0 ) {
   sw   $t0,4($sp)   # save $t0 on our stack
   jal   putint       # putint() (putint will deliberately use and modify $a0)
   lw   $t0,4($sp)   # restore $t0
   # }
onedig:   move   $a0, $t0
   li    $v0, 11
   syscall           # putc #$t0
   #putc   $t0       # output the digit character $t0
   lw   $ra,0($sp)   # restore return address
   addi   $sp,$sp, 8   # restore stack
   jr   $ra       # return

sprintf with formatters Overview familiar with primo.the il explain how it worR started Argument passing using the Stack all the Project Details the tall of the nal sprintf output Addis The For decimal do both and The check. Wow should provided modity for

Explanation / Answer

format:   .asciiz "string: |%-5d|%-5d|%5d|%5.5d|%+d|%.5d "
                   # null-terminated string of
                   # ascii bytes. Note that the
                   # counts as one byte: a newline
                   # character.
chrs:   .asciiz " characters: "   # null-terminated string at
                   # address 'chrs'

# The "text" of the program is the assembly code that will
# be run. This directive marks the beginning of our program's
# text segment.

   .text
  
# The sprintf procedure (really just a block that starts with the
# label 'sprintf') will be declared later. This is like a function
# prototype in C.

   .globl sprintf
      
# The special label called "__start" marks the start point
# of execution. Later, the "done" pseudo-instruction will make
# the program terminate properly.  

main:
   addi   $sp,$sp,-36   # reserve stack space

   # $v0 = sprintf(buffer, format, 1, 2, 3, 4, 5, 6)
  
   la   $a0,buffer   # arg 0 <- buffer
   la   $a1,format   # arg 1 <- format
   addi   $a2,$0,1   # arg 2 <- 1
   addi   $a3,$0,2   # arg 3 <- 2
   addi $t0,$0,3  
   sw   $a3,16($sp)   # arg 4 <- 3
  
   addi   $t0,$0,4
   sw   $t0,20($sp)   # arg 5 <- 4 ('o', as a character)
  
   addi   $t0,$0, 5
   sw   $t0,24($sp)   # arg 6 <- 5

   addi $t0,$0, 6
sw $t0,28($sp) # arg 7 <- 6

   sw   $ra,32($sp)   # save return address
   jal   sprintf       # $v0 = sprintf(...)

   # print the return value from sprintf using
   # putint()

   add   $a0,$v0,$0   # $a0 <- $v0
   jal   putint       # putint($a0)

   ## output the string 'chrs' then 'buffer' (which
   ## holds the output of sprintf)

    li    $v0, 4  
   la    $a0, chrs
   syscall
   #puts   chrs       # output string chrs
  
   li   $v0, 4
   la   $a0, buffer
   syscall
   #puts   buffer       # output string buffer
  
   addi   $sp,$sp,36   # restore stack
   li    $v0, 10       # terminate program
   syscall

# putint writes the number in $a0 to the console
# in decimal. It uses the special command
# putc to do the output.
  
# Note that putint, which is recursive, uses an abbreviated
# stack. putint was written very carefully to make sure it
# did not disturb the stack of any other functions. Fortunately,
# putint only calls itself and putc, so it is easy to prove
# that the optimization is safe. Still, we do not recommend
# taking shortcuts like the ones used here.

# HINT:   You should read and understand the body of putint,
# because you will be doing some similar conversions
# in your own code.
  
putint:   addi   $sp,$sp,-8   # get 2 words of stack
   sw   $ra,0($sp)   # store return address
  
   # The number is printed as follows:
   # It is successively divided by the base (10) and the
   # reminders are printed in the reverse order they were found
   # using recursion.

   remu   $t0,$a0,10   # $t0 <- $a0 % 10
   addi   $t0,$t0,'0'   # $t0 += '0' ($t0 is now a digit character)
   divu   $a0,$a0,10   # $a0 /= 10
   beqz   $a0,onedig   # if( $a0 != 0 ) {
   sw   $t0,4($sp)   # save $t0 on our stack
   jal   putint       # putint() (putint will deliberately use and modify $a0)
   lw   $t0,4($sp)   # restore $t0
   # }
onedig:   move   $a0, $t0
   li    $v0, 11
   syscall           # putc #$t0
   #putc   $t0       # output the digit character $t0
   lw   $ra,0($sp)   # restore return address
   addi   $sp,$sp, 8   # restore stack
   jr   $ra       # return

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote