reference:
https://mklimenko.github.io/english/2018/06/19/write-only-variables/
There are basically three types of registers:
https://godbolt.org/g/1ro2FN
https://mklimenko.github.io/english/2018/06/19/write-only-variables/
There are basically three types of registers:
- Read-write
- Read-only
- Write-only
volatile auto &read_write = *reinterpret_cast<std::uint32_t*>(register_address);Read-only:
const volatile auto &read_only = *reinterpret_cast<std::uint32_t*>(register_address);Code:
https://godbolt.org/g/1ro2FN
constexpr std::size_t register_address = 123456; const volatile auto &read_only = *reinterpret_cast<std::uint32_t*>(register_address); void foo() { auto dst = read_only; }
/// Disassembly: foo(): mov eax, DWORD PTR ds:123456 ret
class Register { private: static volatile inline std::uint32_t &ref = *reinterpret_cast<std::uint32_t*>(register_address); public: static std::uint32_t Get(){ return ref; } static void Set(std::uint32_t val){ ref = val; } };Final code: https://godbolt.org/g/gQR1wd
#include <cstdint> #include <type_traits> template <std::size_t address> class Register { private: static volatile inline std::uint32_t &ref = *reinterpret_cast<std::uint32_t*>(address); public: Register& operator=(std::uint32_t val){ ref = val; return *this; } template <typename T> operator T() const{ static_assert(std::is_same_v<T, std::uint32_t>, "You should assign this register to the std::uint32_t value"); return T(); } operator std::uint32_t() const { return ref; } }; Register<1234567> reg; void RegGet() { auto dst = reg; } void RegSet(std::uint32_t val) { reg = val; }write-only:
template <std::size_t address> class Register { private: static volatile inline std::uint32_t &ref = *reinterpret_cast<std::uint32_t*>(address); public: static void Set(std::uint32_t val){ ref = val; } Register& operator=(std::uint32_t val){ ref = val; return *this; } };read-only:
template <std::size_t address> class Register { private: static volatile inline std::uint32_t &ref = *reinterpret_cast<std::uint32_t*>(address); public: static std::uint32_t Get(){ return ref; } template <typename T> operator T() const{ static_assert(std::is_same_v<T, std::uint32_t>, "You should assign this register to the std::uint32_t value"); return T(); } operator std::uint32_t() const { return ref; } };
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.