Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

File to edit sprintf ~~~~~~~~~~~~~~~~~ #sprintf! #$a0 has the pointer to the buffer to be printed to #$a1 has the pointer to the format string

image

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 '0') 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 You may choose to do this project by yearulf or with a partan. This project is to make you familiar with MIPS coding and also blaay representace of hers. It will be your tak to change from the computer representation to the human seadable form, ie character. Note that the number is not the same as hor 0 dook at their ASCII). If you are not familiar with sprint, then write a small C program where instead of using print, you will spent. It is nically the behavior except the whole output string is put into a bater (you supply) instead of the cele cupt. Since printspris can take variable scent of agreb (je more than 4) we need to aso stack-orgument passing pronocol. The following section will explain how it works serbe you get started. Argument passing using the Stack The MIPS lingvis registen ad-fa3 for passing argumes down to procedures. If there are more than four, the remaining arguments are passed on the stack. Each argument gets one word of stock space. Suppose we are trying to write in MIPS assembler a program like thi int foo (int x, ist y, ist quux, ise bax, int haz) int a, b 1 int rais ( 1 a ye nein: Procedare forventer age. The space for the agents allocated on the stack as part of the caller's cke. In other word, main, net soos allocate the space. The agents go at the botter of main's stak frame. That is, main will use 0Sep) to hold the arguments and 45p) to hold the argumenty. The first orgument is always of the top of the stack, yes have to be consistent about this so that too knows which argument is which. NB: Sack space in alluxased for all agents, even shore which are pred in the S registers. There are not pat on the sick, hat stack space is nonetheless for the fool int c. d too (3, 4, 43, 62, 1); adii $t0, 30, 3 adii $11, 00, addi Ssp, Sep, 12 make stack space for words: Sra, e, d, and # SV Sa, 21 (5) 30, 24135p) w 31, 20(sp) 900, 50, 400 add $41, 80, 812 addi a2, 90, 43 addi a3, 90, 62 oddi $80, 40, 1 zv 060, 1610apl jal foo addi Sap. Sap. 32 lv 3-4135p je addi Sep, $sp, -12 822, 818001 $50, 90, $al Sel, 28(Stp) assume this holds the value of e assue this holds the value of d add lv the age . Y quan, bax, baz ve Sra I save a before calling foo e #saved before calling foo +arg x = e arg y = d targ que - + bar = 62 + baz 1, but no more regiotero - +30 paas on the atack 43 + restore stack space reload return address return to celler #rake stack space for 3 words: 3ra, a, b t gat argument y +(000 below) +12 (1ooo Exone) + 16 28 up on stack + fetched argument baz addi Sap. Sp. 12+ restore stack space lv $16. -4(0) +reload return address je tra return to caller The instruction indicated by is the key to understanding the sock method of argument passing. Procedare fonferring to a word of stock memory that is from the caller's stuck frame. Its own frame includes only the the wond050) 4spand Project Details Wike a MIPS assembly language implementation of a fiction very similar to the C function sprintf int aprintf (char "outeaf, char tomas,...) aprintf works like peint.except that it writes to the string of instead of totdandet. axamed already to polas to allocated memory sufficient to hold the genered duracire nan sprintf for more information. Your function must accept any number of arguments, passed according to MIPS sanded convention Stack space is allocated for all the agents, but the fint four arguments are passed in seg anyway their space is used. The find four arguments are passed in the Sa0-5a3 registers, and there are passed on the stack. The first argument is the address of a chancer amay into which your procedure will put its results. The second aga is the address of a format string in which cach occanece of a pescent sign (9) indicates where one o is the bed and how it to be forward. The remaining argumas a vala that are to become to printable character form seconding to the format instructions, sprintt retumsthe number of characters in its output string not including the wall at the end. You do not have to do any amor checking (eg. comparing the number of arguments to the maker of specification). You also do not have to implancer all of the formatting options of the real sprintf. Here are the ones you a to implement wieder argument to unsigned decimal (tre the sestargament as an unsigned integer and outpat in decimal) dinger agarnt to raigned betadecimal(treat the rest arguments and inter and output in base 16) unsigned integragance to signed octal (treat the next orgement as an unsigned anger and in base Additionally you will implement two mos that are more complicated since they need to implement procision and wil. The precision is written in the formet "aber where the warber determines masiman number of charaders to print. The width is weites es jet "amber indetermine the minieraber of duracers. The two can be combined to board both min and max of duraciers to printing amberber in the delimiter. You can oume that both precision and with will be single digis (9): includes string of chances in ostet treat the angamont as a pointer to all-termined string to be cepial to the out It should pristchurcsatlant ..shed pris: 9 characters at most 55 should prist between 5-9 For decinal, you will want to implement both precision and width. You will need to do both plas and minsfag for decirnal. The pho sign will include the sign specifier for the maker. signinger argument to signed decimal(teat the next argument as a signed integer and ou in decine) %5 kould print 5 characters lead %d:ksbodd print 9 cherseits 55.9d: 1: could prist between 5.9 5+:pris+ if the manber i posve It will left-justify the outper instead of leading Mank spaces (if any) The delineand formations can be combined to form more than one and we provide you some budes to do sonity check. You should create your own tests as these are minimal and not meant to be comprehensive. You can copy the basic structure provided here and modity for your own s

Step by Step Solution

3.34 Rating (154 Votes )

There are 3 Steps involved in it

Step: 1

format asciiz string 5d5d5d55dd5d nullterminated string of ascii bytes ... blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Calculus

Authors: Dale Varberg, Edwin J. Purcell, Steven E. Rigdon

9th edition

131429248, 978-0131429246

More Books

Students also viewed these Programming questions

Question

What is a cultural formula? Give an example.

Answered: 1 week ago

Question

Evaluate Or show that it diverges? 1 dx 1xV-Inx -In/x

Answered: 1 week ago