diff --git a/src/simudator/gui/dialogs/memory_content_dialog.py b/src/simudator/gui/dialogs/memory_content_dialog.py
index 4bbeb63196470fbe1de36d5b53ecf1109531cb7e..732a564fc18895783810d94dfe09a43134709dc9 100644
--- a/src/simudator/gui/dialogs/memory_content_dialog.py
+++ b/src/simudator/gui/dialogs/memory_content_dialog.py
@@ -1,65 +1,281 @@
-from typing import Optional
+from math import ceil
 
 from qtpy.QtCore import Qt
 from qtpy.QtCore import Signal as pyqtSignal
 from qtpy.QtWidgets import (
-    QComboBox,
+    QButtonGroup,
     QDialog,
+    QErrorMessage,
     QHBoxLayout,
-    QLineEdit,
-    QPushButton,
+    QHeaderView,
+    QRadioButton,
+    QTableWidget,
+    QTableWidgetItem,
+    QVBoxLayout,
     QWidget,
 )
 
-from simudator.core import Module
+from simudator.core.modules import Memory
+from simudator.gui.formatting import Format, FormatInfo, format_to_str
+
+
+class MemoryTable(QTableWidget):
+    """
+    A class showing the contents of a memory module in a QTableWidget.
+
+    This class assumes that the size of the memory module will remain constant.
+
+    Parameters
+    ----------
+    memory_module: Memory
+        An instance of the Memory base class.
+    column_size: int
+        An integer specifying the number of columns, optional.
+    format_info : FormatInfo
+        Optional formatter for formatting each cell in the memory table.
+
+    """
+
+    state_edited = pyqtSignal()
+
+    def __init__(
+        self,
+        memory_module: Memory,
+        format_info: FormatInfo | None = None,
+        column_size=-1,
+    ):
+
+        super().__init__()
+        self._format_info = format_info
+        self._memory = memory_module
+        self._column_size = column_size
+        self._memory_size = len(self._memory.get_state()["memory"])
+        self._set_column_size()
+        self.setColumnCount(self._column_size)
+        rows = ceil(self._memory_size / self._column_size)
+        self.setRowCount(rows)
+        self._init_table_items(self._column_size, rows)
+        self.setHorizontalHeaderLabels(["+" + str(i) for i in range(4)])
+        self.set_editable(False)
+        self._errorMessageWidget = QErrorMessage()
+
+        vertical_headers = []
+        for i in range(0, self._memory_size, self._column_size):
+            vertical_headers.append(str(hex(i)))
+
+        self.setVerticalHeaderLabels(vertical_headers)
+
+        self._tt = 0
+        self.update()
+
+        # Signal used to detect when the user has edited a cell
+        # This code can only be called after the initial self.update().
+        # When the QTableWidget is initialized it currently fills each celll with empty strings.
+        # It also signals cellChanged for each cell it initializes. Thus _on_cell_changed
+        # is called for each cell and tries to save the cells empty string into the modules memory as
+        # an integer.
+        self.cellChanged.connect(self._on_cell_changed)
+
+    def update(self):
+        """
+        Update the content of this widget to reflect the content of the memory module.
+        """
+        print(self._tt)
+        self._tt += 1
+        memory_content = self._memory.get_state()["memory"]
+        for i in range(self._memory_size):
+            value = memory_content[i]
+            row = i // self._column_size
+            col = i % self._column_size
+
+            if self._format_info:
+                value = format_to_str(self._format_info, value)
+                print("-" * 20)
+                print(self._format_info.selected_format)
+                print(value)
+                print("-" * 20)
+            else:
+                value = str(value)
+
+            if value != "":
+                self.set_item(row, col, value)
+
+    def set_item(self, row: int, col: int, text: str) -> None:
+        """Set the text at specified table cell to the given text.
+
+        Parameters
+        ----------
+        row: int
+             The items row position in the table.
+        col: int
+             The items column position in the table.
+        text: str
+             The text to be displayed.
+        """
+        item = QTableWidgetItem(text)
+
+        self.setItem(row, col, item)
+
+    def set_editable(self, editable: bool) -> None:
+        """
+        Set the text to be editable on ``True``, uneditable on ``False``.
+
+        Parameters
+        ----------
+        editable: bool
+            Sets the text to be editable on ``True``, uneditable on ``False``.
+
+        """
+        if editable:
+            self.setEditTriggers(self.AllEditTriggers)
+        else:
+            self.setEditTriggers(self.NoEditTriggers)
+
+    def _init_table_items(self, cols: int, rows: int) -> None:
+        for col in range(cols):
+            for row in range(rows):
+                item = QTableWidgetItem()
+                self.setItem(row, col, item)
+
+    def _set_column_size(self) -> None:
+        """
+        Set the column size to a reasonable value if the size was not given to the constructor.
+
+        This function assumes that the attributes `column_size` and `memory_size` are set before it is called.
+        """
+
+        if not self._column_size == -1:
+            return
+
+        if self._memory_size > 200:
+            self._column_size = 4
+            return
+
+        if self._memory_size > 100:
+            self._column_size = 2
+            return
+
+        self._column_size = 1
+        return
+
+    def _on_cell_changed(self, row, col):
+        state = self._memory.get_state()
+        item = self.item(row, col)
+        value = item.text()
+        if value == "":
+            return
+        index = row * self._column_size + col
+        state['memory'][index] = value
+        self._memory.set_state(state)
+        self.state_edited.emit()
 
 
 class MemoryContentDialog(QDialog):
-    accepted = pyqtSignal(str, str, str, name="accepted")
+    """
+    A dialog for letting the user edit the state of a processor modules memory.
+
+    Parameters
+    ----------
+    module : Module
+        The module to edit the memory of.
+    parent : QWidget | None
+        Optional parent widget of this dialog.
+    flags : Qt.WindowFlags | Qt.WindowType
+        Optional window flags for the window of the dialog.
+    format_info : FormatInfo
+        Optional formatter for formatting each cell in the memory table.
+    """
+
+    state_edited = pyqtSignal()
 
     def __init__(
         self,
-        memory: Module,
-        parent: Optional['QWidget'] = None,
+        memory_module: Memory,
+        parent: QWidget | None = None,
         flags: Qt.WindowFlags | Qt.WindowType = Qt.WindowFlags(),
+        format_info: FormatInfo | None = None,
     ) -> None:
         super().__init__(parent, flags)
+        self._memory_module = memory_module
+        self._format_info = format_info
+
+        self._add_layout()
+        self._add_edit_buttons()
+        self._add_formatting_buttons()
+
+        # Sets the size of each column to the smallest possible width that allows all content in each box to be visible self._memory_table.horizontalHeader().setSectionResizeMode(
+        self._memory_table.horizontalHeader().setSectionResizeMode(
+            QHeaderView.ResizeToContents
+        )
+        self._memory_table.update()
+
+    def _add_layout(self):
+
+        # Create a layout that expands vertically
+        # so that the buttons can be displayed below the
+        # memory content
+        self._layout = QVBoxLayout(self)
+        self._memory_table = MemoryTable(self._memory_module, self._format_info)
+        self._memory_table.state_edited.connect(self.state_edited)
+        self._layout.addWidget(self._memory_table)
+
+    def _add_edit_buttons(self):
+
+        # Create edit/view buttons, they are exclusive by default
+        self._edit_button = QRadioButton("Edit")
+        self._view_button = QRadioButton("View")
+        self._edit_group = QButtonGroup()
+        self._edit_group.addButton(self._edit_button, 1)
+        self._edit_group.addButton(self._view_button, 2)
+
+        # Connect them to the 'set_edit' function
+        self._edit_group.buttonClicked.connect(self._set_edit)
+        self._edit_button_layout = QHBoxLayout()
+        self._edit_button_layout.addWidget(self._edit_button)
+        self._edit_button_layout.addWidget(self._view_button)
+        self._layout.addLayout(self._edit_button_layout)
+
+        # Set the memory to be uneditable on startup
+        self._view_button.toggle()
+
+    def _add_formatting_buttons(self):
 
-        self.memory = memory
-        self.memory_name = memory.get_state()['name']
+        # If format info is 'None' do nothing
+        if not self._format_info:
+            return
 
-        adresses = [str(i) for i in range(len(memory.get_state()['memory']))]
+        # If there are no supported_formats we want to avoid creating
+        # a new button group since it will take up space that is not used
+        if len(self._format_info.supported_formats) == 0:
+            return
 
-        self.adressSelectWidget = QComboBox()
-        self.adressSelectWidget.addItems(adresses)
-        self.adressSelectWidget.activated.connect(self.updateValue)
-        self.adressSelectWidget.setEditable(True)
+        self._format_group = QButtonGroup()
+        self._format_button_layout = QHBoxLayout()
+        format_names = [format.name for format in self._format_info.supported_formats]
 
-        self.valuesWidget = QLineEdit()
+        # Create formatting buttons, they are exclusive by default
+        # Each button will be mapped to the value of the enums
+        for format in Format:
 
-        okButton = QPushButton('OK')
-        okButton.clicked.connect(self.signalAccepted)
-        cancelButton = QPushButton('Cancel')
-        cancelButton.clicked.connect(self.close)
+            name = format.name
+            id = format.value[0]
 
-        hboxLayout = QHBoxLayout()
-        hboxLayout.addWidget(self.adressSelectWidget, 0)
-        hboxLayout.addWidget(self.valuesWidget, 1)
-        hboxLayout.addWidget(okButton)
-        hboxLayout.addWidget(cancelButton)
-        self.setLayout(hboxLayout)
+            if name in format_names:
+                button = QRadioButton(name)
+                self._format_group.addButton(button, id)
+                self._format_button_layout.addWidget(button)
 
-        self.show()
-        self.updateValue()
+        self._layout.addLayout(self._format_button_layout)
+        self._format_group.buttonClicked.connect(self._set_format)
 
-    def updateValue(self) -> None:
-        selectedAdress = int(self.adressSelectWidget.currentText(), 16)
-        memory_content = self.memory.get_state()['memory']
-        value = memory_content[selectedAdress]
-        self.valuesWidget.setText(str(value))
+    def _set_edit(self):
+        pressed_button_id = self._edit_group.checkedId()
+        if pressed_button_id == 1:
+            self._memory_table.set_editable(True)
+        if pressed_button_id == 2:
+            self._memory_table.set_editable(False)
 
-    def signalAccepted(self) -> None:
-        adress = self.adressSelectWidget.currentText()
-        enteredValues = self.valuesWidget.text()
-        self.accepted.emit(self.memory_name, adress, enteredValues)
-        self.close()
+    def _set_format(self):
+        pressed_button_id = self._format_group.checkedId()
+        self._format_info.selected_format = pressed_button_id
+        self._memory_table.update()
diff --git a/src/simudator/gui/dialogs/module_state_dialog.py b/src/simudator/gui/dialogs/module_state_dialog.py
index fc768d7ade04490453e641d1f77fc3e2d5a76266..7f9399b9bb097c0ed0e826056711c800bbae2823 100644
--- a/src/simudator/gui/dialogs/module_state_dialog.py
+++ b/src/simudator/gui/dialogs/module_state_dialog.py
@@ -104,4 +104,3 @@ class ModuleStateDialog(QDialog):
         except ValueError as e:
             # TODO: error handling
             pass
-
diff --git a/src/simudator/gui/module_graphics_item/actions.py b/src/simudator/gui/module_graphics_item/actions.py
index c1abb1f5f37d1f974e2816e03fe39a8af5e1a6c8..c4334a66b1feecf7a9a4dcdd719fce139493fb57 100644
--- a/src/simudator/gui/module_graphics_item/actions.py
+++ b/src/simudator/gui/module_graphics_item/actions.py
@@ -3,7 +3,9 @@ from enum import Enum, auto
 from PyQt5.QtWidgets import QAction
 
 from simudator.core.module import Module
+from simudator.gui.dialogs.memory_content_dialog import MemoryContentDialog
 from simudator.gui.dialogs.module_state_dialog import ModuleStateDialog
+from simudator.gui.formatting import FormatInfo
 from simudator.gui.module_graphics_item.module_widget import ModuleWidget
 
 
@@ -14,6 +16,7 @@ class ActionType(Enum):
     """
 
     EditState = (auto(),)
+    EditMemory = (auto(),)
 
 
 def edit_state_action(module: Module, module_widget: ModuleWidget) -> QAction:
@@ -41,6 +44,42 @@ def edit_state_action(module: Module, module_widget: ModuleWidget) -> QAction:
     def action_triggered():
         dialog = ModuleStateDialog(module, module_widget)
         dialog.state_edited.connect(module_widget.state_changed)
+        dialog.exec()
+
+    action.triggered.connect(action_triggered)
+    return action
+
+
+def edit_memory_action(
+    module: Module, module_widget: ModuleWidget, format_info: FormatInfo | None = None
+) -> QAction:
+    """
+    Create a QAction for opening a memory-edit dialog for a module widget.
+    The dialog triggers the state_changed signal of the module widget if the
+    user edites the contentet in the dialog.
+
+    Parameters
+    ----------
+    module : Module
+        The module that should be edited when triggering the created edit action.
+    module_widget : ModuleWidget
+        The module widget for the module that should be edited. Used for
+        displaying and parsing information correctly.
+    format_info : FormatInfo
+        Optional formatter for formatting each cell in the memory table.
+
+    Returns
+    -------
+    QAction
+        A Qt action for opening a dialog for editing the state of a modules memory.
+        Intended to be added as an action to the given module widget.
+    """
+    action = QAction("Edit memory", module_widget)
+
+    def action_triggered():
+        dialog = MemoryContentDialog(module, format_info=format_info)
+        dialog.state_edited.connect(module_widget.state_changed)
+        dialog.exec()
 
     action.triggered.connect(action_triggered)
     return action
@@ -64,4 +103,3 @@ def toggle_ports_action(module_widget: ModuleWidget) -> QAction:
     action = QAction("Toggle ports", module_widget)
     action.triggered.connect(module_widget.toggle_ports)
     return action
-
diff --git a/src/simudator/gui/module_graphics_item/integer_memory_graphic.py b/src/simudator/gui/module_graphics_item/integer_memory_graphic.py
index 4902f59be8670a117cfd8665d1385ce16462e656..4e4ea6bbf40c22d2702698b26682dc8c52cbe6dd 100644
--- a/src/simudator/gui/module_graphics_item/integer_memory_graphic.py
+++ b/src/simudator/gui/module_graphics_item/integer_memory_graphic.py
@@ -1,5 +1,3 @@
-import sys
-import traceback
 from enum import Enum
 
 from qtpy.QtWidgets import QButtonGroup, QHBoxLayout, QHeaderView, QRadioButton
diff --git a/src/simudator/gui/processor_handler.py b/src/simudator/gui/processor_handler.py
index e0ccb9ac0f5fe249540a5304ea10ad4cb149dff3..9bf8937d51a031f8f2fff4501e1915036b46295a 100644
--- a/src/simudator/gui/processor_handler.py
+++ b/src/simudator/gui/processor_handler.py
@@ -340,4 +340,3 @@ class ProcessorHandler(QObject):
         by the user.
         """
         pass
-
diff --git a/src/simudator/processor/mia/mia.py b/src/simudator/processor/mia/mia.py
index eb52e58dabea5bc3e02b62ac1e12a4511046c7d5..8d771888ea1d16ad00b4626abc4eceb9a80fa668 100644
--- a/src/simudator/processor/mia/mia.py
+++ b/src/simudator/processor/mia/mia.py
@@ -4,6 +4,9 @@ from simudator.cli.cli import CLI
 from simudator.core.modules.integer_register import IntegerRegister
 from simudator.core.processor import Processor, Signal
 from simudator.gui.gui import GUI
+from simudator.gui.module_graphics_item.actions import edit_memory_action, edit_state_action
+from simudator.gui.module_graphics_item.module_widget import ModuleWidget
+from simudator.gui.formatting import Format, FormatInfo
 from simudator.processor.mia.gui import (
     AluGraphicsItem,
     ArGraphicsItem,
@@ -384,6 +387,18 @@ class MIA_CPU(Processor):
             widget = MiaMemoryGraphicsItem(module)
             gui.add_module_graphics_item(widget)
 
+        pm = self.get_module("PM")
+        gui_pm = ModuleWidget(pm, {}, [])
+        action = edit_memory_action(pm, gui_pm, FormatInfo(FormatInfo.NUMERICAL_FORMATS, Format.Hex, bit_length=16))
+        gui_pm.addAction(action)
+        gui.add_module_widget(gui_pm)
+
+        ar = self.get_module("AR")
+        gui_ar = ModuleWidget(ar, {"value": FormatInfo(FormatInfo.NUMERICAL_FORMATS, Format.Hex, bit_length=16)}, [])
+        action = edit_state_action(ar, gui_ar)
+        gui_ar.addAction(action)
+        gui.add_module_widget(gui_ar)
+
         gui.add_all_signals()
 
         gui.show()