Writing directly to the Register Address. Safe or Unsafe?

Reading Time: 4 minutes

Hi again, I am back to discuss one more interesting blog today which will help you in preventing errors while working with hardware registers. This will tell you what can happen if you put Invalid Address on the register.

As we are working with the Embedded Systems they make our task fast and reliable. Also, they are much smaller in size compared to traditional computers, which makes them compact and portable, and useful for mass production. Management of Embedded Systems is pretty easy, as elements used in their creation are cheap & long-lasting. Embedded Systems are also cost-effective.

Till now we are done with the blinking of LEDs of stm32f3-discovery-board, we have also used the magic address to blink the LEDs. Now to go through this blog you have to read that blog first from here if you have not used the magic address to blink your LEDs.

Magical Address was easy!

As you already know you have used a Magical Address that helps you to write on the GPIO_BSRR register to make your LED “on” or “off” and that makes your task easy as you just note down the value from the User Manual and assign it to the GPIO_BSRR register that makes your LED “on” or “off”.

The disadvantage of using the register’s address directly

Invalid Address

Yes, you can use that particular address to access the BSRR register but not all the peripheral memory can be accessed. If you make any mistake while providing the address then it could generate a Hardware Exception for a read of an Invalid Address. Let’s see how.


Read an Invalid Address

We are going to provide an Invalid Address in place of a Magical Address and then we will try to read that Invalid Address. Let’s see what happens when we go through an Invalid Address.

This is the code we are going to run and the Invalid Address we are going to read to access BSRR -> 0x4800_1800.

Note: Link to the git repository where you can find the code and you can create an issue also if you face any problem.

#![no_main]
#![no_std]
use core::ptr;
/// This program is going to read an INVALID ADDRESS using Raw Pointer.
use cortex_m_rt::entry;
use panic_itm as _;
use stm32f3_discovery::stm32f3xx_hal::prelude::*;


#[entry()]
fn main() -> ! {
    unsafe {
        ptr::read_volatile(0x4800_1800 as *const u32);
    }

    loop {}
}

You can notice that this 0x4800_1800 is close to the GPIOE_BSRR address we used before but this is an Invalid Address. Invalid in the sense that there’s no register at this address.

Now let’s build and run this code. If you don’t know how to build and run the code on Hardware/Bare metal then you need to read this blog.


Build & Run

Okay so after building and running the code. Let’s load the code inside the hardware and provide some more commands.

After providing the “continue command you can see how the program gives a HardFault.

What happened? Why program stopped?

This happened because we tried to do an invalid operation, reading memory that doesn’t exist, so the processor raised an exception, hardware exception. So whenever you try to read an invalid address the processor will raise an exception handler.

  • Exceptions break the normal flow of a program and force the processor to execute an exception handler, which is just a function/subroutine.
  • Different types of conditions raise different exceptions and different exception handlers handle different exceptions.
  • Here cortex-m-rt crate defines a default hard fault handler, named HardFault, that handles the “invalid memory address” exception.

Break at HardFault

Openocd.gdb file contains the statement which set a breakpoint at HardFault and that’s why the debugger halted the program automatically while debugging the exception handler.

We can know more about this situation. Let’s see put command “list“.

ef" is a snapshot of the program state right before the exception occurred.

Let’s see what “ef” contains. Put command print/x *ef.


print/x *ef

Here we only need to focus on the “pc-Program Counter” field. The address in this register points to the instruction that generated the exception. We need to go deep down with the pc to know exactly which register cause the exception.

Put command disassemble /m ef.pc to get the details of Program Counter.


disassemble /m ef.pc

  • If you see then this is the address on the first line which is present inside the program counter and this is pointing to the instruction which causes the exception to happen.
  • The exception was caused by the ldr r0, [r0, #0] instruction, a read instruction. The instruction tried to read the memory at the address indicated by the r0 register. 
  • Now if you want to know what this r0 contains that cause the exception then go again to the exception frame by putting the command print/x *ef

I think now you understand why this exception occurs and which register causes this. Now you know the mistake of writing an invalid address to the register.

I hope you liked this blog. I’ll see you in the next blog. Thanks for Reading.


If you want to read more content like this?  Subscribe to Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe to Rust Times Newsletter: https://bit.ly/2Vdlld7.

rust times for invalid address

Written by 

Nitin is a Software Consultant, with experience of more than 7 months. He works on Rust Programming Language and Embedded Development using Rust. He is also fond of Java Programming & Artificial Intelligence. Apart from that, his hobbies are Watching Netflix, Reading, Singing & Writing.

2 thoughts on “Writing directly to the Register Address. Safe or Unsafe?5 min read

Comments are closed.