Uploaded by yofad66007

Lab 3 handout

ENGR 478
Lab 3: Introduction to the Keil MDK Development Tool and Assembly
Xiaorong Zhang
Install and run Keil uVision on your personal computer. The software installation instruction
can be downloaded from the Required Lab kit and Software section on Canvas.
The general purpose of this lab is to familiarize you with the ARM Cotex-M4 instruction set
architecture (ISA) and the software development steps using the Keil MDK simulator. Starting with
Lab 3, we will use Keil MDK for both simulation and debugging on the real board, but for this lab,
we will use just the simulator. You will learn how to develop and simulate assembly programs
using Keil MDK. Through a graphical user interface, the programmer can monitor program
execution and the status of the simulated microcontroller including the CPU registers and memory.
Software skills you will learn include variable initialization, memory access instructions, arithmetic
operations, condition code flags, and branching.
➢ ARM Assembler Directives
➢ Textbook Appendix B: Cortex-M3/M4 Instructions
➢ Cortex-M3/M4F Instruction Set Technical User’s Manual (Canvas ->Other Reference
➢ Thumb-2 Instruction Set Quick Reference Card (Canvas-> Other Reference Materials)
Demonstration and Submission
You will have one week to complete the lab. You can discuss with your group members and
complete the lab work together. The weekly lab work is done within student groups of no more
than three individuals. A post-lab report is required to be submitted individually for each lab. While
the lab demo is evaluated on a group basis, the post-lab report is evaluated on an individual basis.
Every student will need to write and submit a lab report to Canvas->Labs->Lab3 report submission.
The lab report should include
Your name, email and SFSU ID
Your lab group members’ names
The answers to all the questions listed on Page 9
1. Do you feel you achieved the objectives of this lab?
2. What skills do you feel you developed during this lab?
3. Were there any unexpected issues or obstacles that arose during the lab? How did
you address them?
4. If you worked in a group, how did team dynamics affect your performance and
understanding of the lab material?
5. Are there questions you still have or concepts you're not entirely clear on after
completing the lab?
6. Do you have any recommendations for how the lab could be improved in terms of
structure, content, or delivery?
If you finish the lab experiments during the lab time, please demonstrate your results to the
instructor. The instructor may ask questions regarding your program. The latest demonstration time
will be the beginning of next lab. The lab report is due the Sunday following the lab demo deadline.
ENGR 478
Before you start the tutorial, make sure you have installed all the software tools.
1. Download the project M1M2.zip from Canvas->Labs->Lab3->M1M2. This project serves as an
illustrative Assembly project for our simulation using the Keil MDK during this lab. To organize
your work effectively, establish an ENGR 478 work folder on your local computer. Store the M1M2
sample project archive within this designated work folder and then extract its contents.
2. Navigate to the extracted M1M2 folder and then double-click on the M1M2 uVision5 Project file
(see Figure 1).
Figure 1
3. The M1M2 project will load in the Keil MDK (see Figure 2). In the Project window on the left
side, there are three .s files under Source Group 1. Specifically, the files named
"startup_stm32l476xx.s" and "stm32l476xx_constants.s" encompass assembly source code that
defines crucial elements such as the stack, reset vector, and interrupt vectors. It's important to note
that every project within this course will incorporate a "startup_stm32l476xx.s" file, and for the
purposes of this lab, there is no requirement to modify this particular file. The third file, titled
"main.s," contains the essential source code for the main routine of the M1M2 project. This file
encompasses the core functionality that drives the operations of the M1M2 project.
Figure 2
ENGR 478
4. Compile the project by selecting Project->Rebuild all target files or directly clicking on the
Rebuild button as shown in Figure 3. Upon performing this action, the Build Output window
should display a count of 0 errors and 0 warnings, signifying a successful compilation process.
Figure 3
5. Prior to initiating the program simulation, it is necessary to configure the Debug settings. To
proceed with this, navigate to the "Project" menu, then opt for "Options for Target 'Target 1'."
Alternatively, you can directly click on the designated button, as denoted in Figure 4. A new
window will appear; within this pop-up window, select the "Debug" tab and ensure to select the
checkbox labeled "Use Simulator," as shown in Figure 4.
Figure 4
ENGR 478
6. You are now ready to start program simulation. Select Debug->Start/Stop Debug Session to
trigger the initiation of the simulation (see Figure 5). As the simulation begins, several essential
monitor windows will become visible, as shown in Figure 6. These monitor windows include the
Registers Window, Disassembly Window, Source Code window, and Memory 1 Window. Each of
these windows contributes to providing a comprehensive view of the simulation or debugging
process and its various components.
Figure 5
7. In the source code editing window, you will see the symbol
points to the instruction
“LDR r0, =|Load$$RW_IRAM1$$Base|” in the "startup_stm32l476xx.s” file. This symbol serves
as a marker always highlighting the next instruction that the CPU will execute. After a reset
operation, the symbol signifies the initial instruction that will be executed within the project. In this
project, the instruction “LDR r0, =|Load$$RW_IRAM1$$Base|” is the first instruction in the
system’s Reset Handler, which defines the procedure to initialize the system after a reset event.
Figure 6
ENGR 478
8. To simulate the program step by step, click Debug->Step or the
button. Upon each click, a
single instruction will be executed, subsequently updating both the registers and memory to reflect
the execution outcomes. The program counter R15(PC) (displayed in the Registers window on the
left panel) always points to the next instruction to be executed. As you run the “Step” command
for a few times, you will see the
symbol traverse the sequence of instructions outlined within
the Reset_Handler process in the "startup_stm32l476xx.s” file.
Given that this lab focuses on the simulation and observation of the main routine residing in the
"main.s" file, the instruction-by-instruction simulation of the Reset_Handler process can be
bypassed. Instead, you can set up a breakpointer at the instruction you intend to simulate, which in
this case is the first instruction within "main.s." Subsequently, click the "Run" button to directly
progress to the breakpointer. To insert a breakpointer, a simple click to the left of the relevant line
number (as demonstrated in Figure 7) is sufficient. A red dot will then appear next to the targeted
instruction. Subsequent to this setup, execute the "Run" command. As a result, the simulator will
immediately transition from the prior simulated instruction to the instruction indicated by the
breakpointer, specifically the "LDR R1, =M1" instruction within "main.s." By subsequently
clicking the "step" button, you can simulate the instructions line by line within the main routine.
If you want to reset the simulation process, you can click Debug->Reset CPU or the designated
button. If you have made any changes to your program and wish to simulate the changed program,
you must exit the debug mode, rebuild the project, and start the debug session again.
Reset CPU
Run button
Figure 7
9. The Keil MDK uVision Debugger offers robust capabilities to developers. During the debugging
process, developers can access the source code, and can control and analyze program execution at
both high-level (C/C++) and Assembly levels. To learn more about the debug menu and commands,
you can refer to the uVision Help documentation (accessible via Help -> uVision Help -> uVision
User’s Guide). In this particular activity, your focus will be on utilizing the "Step" command. This
command facilitates the execution of the assembly program instruction by instruction.
Simultaneously, you will closely monitor changes in CPU register values and memory content.
ENGR 478
Your objective will be to observe and document the alterations in registers and memory locations
that are pertinent to each step of the program's execution. Further detailed explanations regarding
the Registers window, Disassembly window, and Memory window are provided below:
a. Registers Window (Figure 8): The Registers window shows the content of registers,
microcontroller operation modes, and system and internal states. Through this window, you can
closely monitor the contents stored within both general-purpose registers (R0-R12) and special
registers (SP, LR, PC, and PSR) during the execution of the software program. Additionally, the
ability to expand the xPSR register allows for a granular view of individual bits within the program
status register. The condition flags—N, Z, C, and V—are established through arithmetic and logical
instructions, subsequently influencing conditional code execution.
Figure 8
b. Disassembly Window: The Disassembly Window provides a visual representation of the
program's execution in assembly code. Within this window, you gain insight into crucial details
such as memory addresses, machine code representations, and the corresponding assembly code
for each instruction. Notably, the currently executing instruction is always highlighted for clarity
and focus. In Figure 9, an illustrative example showcases the program counter (R15 PC) pointing
to the initial instruction to execute within the "main.s" file: " LDR R1, =M1". Correspondingly, the
ENGR 478
Registers Window displays the content in the PC register as 0x0800.0220, signifying the memory
address of the upcoming instruction. The Disassembly Window further reinforces this by
highlighting the line starting with 0x0800.0220, signifying the impending execution of the
highlighted instruction. The sequence "4904" is the 16-bit machine code associated with the
instruction " LDR R1, =M1", encompassing the content stored at memory addresses 0x0800.0220
and 0x0800.0221. This machine code aligns with the assembly instruction "LDR r1, [pc, #16],"
presenting an alternative format to express "LDR R1, =M1." This particular format sheds light on
the instruction's addressing mode, identified here as PC relative addressing.
Figure 9
c. Memory Windows: The Memory Windows serve as a visualization of memory areas' contents.
To access a Memory window, navigate to View -> Memory Windows -> Memory 1, as shown in
Figure 10. Upon doing so, you gain the capability to input a specific memory address and
subsequently view the content residing within that designated address. For instance, consider the
32-bit data "M1" within the sample program; its address is 0x2000.0000, as it stands as the foremost
variable defined in SRAM. To explore its content, simply enter 0x20000000 (ensuring the "0x"
prefix) within the Memory 1 Window, as shown in Figure 11. Upon executing this action, the value
attributed to "M1" and stored within the memory range of 0x20000000 to 0x20000003 will be
showcased. At the outset, this value might be represented as "00 00 00 00" in hex.
In essence, the Memory Windows provide an insightful perspective into the information stored
within different memory addresses including flash memory, SRAM, IO registers, and internal
system peripherals, facilitating a comprehensive understanding of program memory utilization.
ENGR 478
Figure 10
Figure 11
11. At this point, you should be familiar with the process of simulating and observing the program's
execution step by step. Before moving forward, take a moment to review the list of questions
outlined on Page 9, which you are expected to address within your forthcoming lab demo and report.
To proceed, your next objective is to simulate the program within the "main.s" file line by line until
the program concludes. Throughout this process, maintain a record of the values attributed to
related registers and memory locations and answer the questions specified on Page 9. This
procedure will allow you to engage in a comprehensive analysis of the program's behavior and
ENGR 478
1. Construct a table in the format shown below to document the values associated with relevant
registers and data during the progressive simulation of the program within the "main.s" file. Please
note that PC, NZCV, R1-R4 represent information within the CPU registers. M1 and M2 are two
specific data entities allocated in the memory.
2. The program within the "main.s" file consists of 1) assembler directives, which provide
instructions for the assembler to perform certain tasks without being converted into machine code
or stored in memory; and 2) assembly instructions are converted into machine instructions by the
assembler. List all the assembly instructions of this program that are converted into machine
3. What are the specific functions of the instructions "M1 SPACE 4" and "NUM DCD 6,"
respectively? Referencing the ARM Assembler Directives, clarify the roles these instructions play.
If the objective is to define a 16-bit constant data labeled "NUM1" with an initial value of 12, write
the code required to achieve this.
4. What memory addresses are assigned to the data entities "M1" and "M2"? Upon completion of
the simulation, what values are stored at these respective memory addresses?
5. Within this program, consider the following components—M1, M2, NUM, and all the assembly
instructions. Identify the specific memory storage categories for storing each of these elements (e.g.,
flash memory, SRAM) using the reference "STM32L47xxx Reference Manual - Chapter 2," which
defines the memory address space for various memory categories.
6. After executing “SUBS R4, R3, #5”, what are the values of the condition code flags? Why?
7. What is the address of instruction “BGT S_2” in memory? What does this instruction do? After
executing this instruction, what is the value stored in the program counter (PC)? Why?
8. Adjust the value of "NUM" to be 3 within the "main.s" file, then simulate the program again.
Upon completion of the simulation, what are the values stored in the memory locations of "M1"
and "M2"?
9. What underlying functionality or logic does this program implement? If you were to implement
this logic utilizing a high-level programming language such as C, illustrate how the code might be
written. You are welcome to utilize any high-level programming language you are familiar with,
or even provide pseudocode to articulate the logic.