Edit: вероятно, есть много способов получить простую константу 1 или -1, которую затем можно использовать для получения любой другой константы. Следующая последовательность кода при необходимости выдает 1
:
jal dummy # puts address of jal+4 into $ra
dummy:
sltu $v0, $0, $ra # sets $v0=1 b/c we know that $ra > 0
Начиная с одной константы, мы можем сдвигать, складывать, вычитать или и т. Д., Чтобы создавать другие константы. 1, сдвинутая влево на 10, дает нам, например, 1024. (Величина сдвига является немедленной, но [10: 6] и поэтому не зависит от вашей гипотетической проблемы.)
Хорошо, теперь, если управляющий сигнал ALUSrc застрял на 0, тогда ALUвсегда получит значение чтения данных Read Register 2.
Идея состоит в том, чтобы использовать это вместе с тем фактом, что аппаратное обеспечение всегда что-то делает, даже если оно не подходит для данной инструкции, например LW
.
По сути, зависший управляющий сигнал ALUSrc
превращает определенные ALU-ориентированные инструкции I-типа в инструкции R-типа - это дает нам lw rt, (ra,rb)
, где эффективный адрес равенra+rb
, а не ra+sxt(imm)
. (В ветвях используется 16-разрядное поле непосредственного доступа, но этот элемент управления на него не влияет; сдвиги используют 5-разрядное немедленное поле, также не используя этот элемент управления.
Это означает, например, что если вы поставитеномер регистра в [15:11] непосредственного поля, ALU получит значение этого регистра (вместо непосредственного).
Так, например, мы можем использовать непосредственное значение [15: 0] извсе нули в LW
, и этот немедленный будет иметь все нули для [15:11], который - с застрявшим ALUSrc - будет получать $ 0 (который содержит ноль) для ALU. Это означает, что мы можем выполнить некоторые базовые инструкции по загрузкесо смещением нуля.
Путем вычисления непосредственного плюс основание и последующего использования lw
/ sw
со смещением нуля, мы можем смоделировать произвольную загрузку или сохранение.