Tip of the day
News
Instructions
Objective
Write a simplified version of PrintF in ARM assembly language.
Requirements and Specifications
For this exercise, you are to write an ARM assembly program that implements a heavily simplifiedversion of the printf function found in the C standard library. Your program will take as input (inspecific registers, your program must use the registers listed for input), the address of a format string to print out (in R1), and the address of a sequence of values (in R2) to interpolate into it.
As with C’s printf(), the format string is composed of zero or more directives: ordinary characters (not ‘%’), which are printed out unchanged; and conversions specifications, which begin with a ‘%’ character. For each conversion specifier encountered in the string, rather than print out the conversion specifier (%s, %d, etc.), your program should instead printout a value of the type specified (string, integer, and so on). These values are specified as a sequence of 32-bit words in memory, with the address of the first value being given to your program in the register, R2.
Some hints for completing this exercise:
- The address of the format string is specified in R1, the address of the values is specified in R2 — if you use other registers, you program will fail in the pipeline. Likewise, you must not add in code before the label printf in the skeleton file, 01-printf.s, or your program will not execute correctly. You may however (and probably should) modify the format strings and sequence of values to ensure your program works correctly with different input.
- Your program will need to loop through every character of the format string, and print out thecharacters (using SWI 0), unless the character is a percent (‘%’) character.
- Your program should stop looping when it reaches a null character in the format string, (i.e. when the byte read from memory has the literal value of zero (not the ASCII code for the character representing the digit zero). You can find this by comparing with #0.
- The format string is made up of characters that are one byte long, you will need to use LDRB toaccess these. The values are all 32-bits (four bytes) long, you will need to use LDR to access these.
- If your program encounters a conversion specifier, (i.e. you read a ‘%’ character from the format string), then your program should fetch the next byte of the format string from memory. Then based on the value of this character, your program should:
- If the conversion specifier is %%, then your program should print out a single percent character. The value of R2 should not be updated.
- If the conversion specifier is %c, then your program should read the 32-bit value from the address currently specified in R2. Your program should treat the value read as an ASCII character and print it out using SWI 0. The value of R2 should be updated to contain the address of the next value in the sequence.
- If the conversion specifier is %d, then your program should read the 32-bit value from the address currently specified in R2. Your program should treat the value read as an unsignedinteger value and print it out using SWI 4. The value of R2 should be updated to contain the address of the next value in the sequence.
- If the conversion specifier is %s, then your program should read the 32-bit value from the address currently specified in R2. Your program should treat the value read as containing the address of a null-terminated string and print it out using SWI 3. The value of R2 should be updated to contain the address of the next value in the sequence.
- Invalid conversion specifiers should print nothing out.
- Bear in mind that each value in the sequence of values is 4 bytes long.
- It can be instructive to consider this program as being formed from two parts. One part of the program is stepping through each character of the format string deciding what needs to be printed (the character, or a value — and for each value, what type of value). The other part of the program is fetching the value from the sequence of values and printing it out based on the type specified in the string. I’d suggest working on the two parts of the program separately, first get the program stepping through the format string printing out dummy values, then when you are confident that part is working, move onto writing the code to read the actual values from memory.
Screenshots of output
Source Code
Printf.s
B main
tstfmt DEFB "%s%c%c\nNumbers: %d %d\n100%% Bad %zformats %ynot printed\n", 0
tststr DEFB "This is a test string",0
ALIGN
seq DEFW tststr,'!','!',1,2
main LDR R1, =tstfmt ; format
LDR R2, =seq ; sequence
printf MOV R3, #0 ; current sequence index
prloop LDRB R0, [R1] ; load character from format string
CMP R0, #0 ; if end of string
BEQ prend ; end print
CMP R0, #'%' ; if not a format specifier
BNE prchar ; print the character
ADD R1, R1, #1 ; else, advance to next character in format string
LDRB R0, [R1] ; load next character from format string
CMP R0, #0 ; if end of string
BEQ prend ; end print
CMP R0, #'%' ; if double percent
BEQ prchar ; print single percent char
CMP R0, #'c' ; if %c
BEQ charfmt ; print using char format
CMP R0, #'d' ; if %d
BEQ intfmt ; print using int format
CMP R0, #'s' ; if %s
BEQ strfmt ; print using string format
B prnext ; else, print nothing
charfmt LDR R0, [R2] ; load value from sequence
ADD R2, R2, #4 ; advance to next position in sequence
B prchar ; print character
intfmt LDR R0, [R2] ; load value from sequence
ADD R2, R2, #4 ; advance to next position in sequence
SWI 4 ; print integer
B prnext ; advance to next char in format
strfmt LDR R0, [R2] ; load value from sequence
ADD R2, R2, #4 ; advance to next position in sequence
SWI 3 ; print string
B prnext ; advance to next char in format
prchar SWI 0 ; print a character
prnext ADD R1, R1, #1 ; advance to next character in format string
B prloop ; repeat loop
prend SWI 2
Breaker.h
B main
width DEFW 20 ; max line width
buffer DEFS 100 ; word buffer
ALIGN
main LDR R1, =width ; load width in R1
LDR R1, [R1]
LDR R2, =buffer ; load buffer address in R2
MOV R3, #0 ; current buffer length
MOV R4, #0 ; current line length
rdloop SWI 1 ; read character
CMP R0, #'#' ; if hash
BEQ quit ; terminate program
CMP R0, #' ' ; if space
BEQ prbuff ; print buffer
CMP R0, #10 ; if newline
BEQ prbuff ; print buffer
STRB R0, [R2, R3] ; else, save char in buffer
ADD R3, R3, #1 ; increment buffer length
B rdloop ; read next char
prbuff MOV R5, R0 ; save space or newline char
CMP R3, #0 ; if there's no info in buffer
BEQ prnline ; go to print newline if needed
prnxt MOV R0, #0 ; save zero in buffer
STRB R0, [R2, R3] ; to mark end of string
ADD R0, R3, R4 ; add length of line plus word
ADD R0, R0, #1 ; add space
CMP R0, R1 ; compare with max width
BLE prword ; if <= width, print the word
MOV R0, #10 ; else, print a newline before the word
SWI 0
MOV R4, #0 ; clear length of line
prword CMP R4, #0 ; if it's the first word
BEQ prskip ; don't print starting space
MOV R0, #' ' ; print a space before the word
SWI 0
ADD R4, R4, #1 ; increment line length
prskip LDR R0, =buffer ; print the buffer
SWI 3
ADD R4, R4, R3 ; add word length to line length
MOV R3, #0 ; reset word length
prnline CMP R5, #10 ; if input was not a newline
BNE rdloop ; read next char
MOV R0, #10 ; else, print a newline
SWI 0
MOV R4, #0 ; clear length of line
B rdloop ; read next char
quit SWI 2
Related Samples
Explore our Assembly Language Assignment samples, providing hands-on solutions to intricate programming challenges. Dive into optimized code snippets for x86 and ARM architectures, covering system calls, memory management, and algorithm implementations. Master Assembly Language with detailed explanations and ready-to-use examples, enhancing your proficiency in low-level programming.
Assembly Language
Word Count
11673 Words
Writer Name:Dr. Denise M. Lopez
Total Orders:500
Satisfaction rate:
Assembly Language
Word Count
3655 Words
Writer Name:Dr. John L. Sanders
Total Orders:900
Satisfaction rate:
Assembly Language
Word Count
11176 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
1782 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
7747 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2371 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
1270 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
5650 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
5768 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
1586 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2204 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
3452 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
6803 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
5272 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2752 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
10514 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2587 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
15048 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
4268 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
4470 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate: