Верните конструкцию двигателя обратно в конструктор автомобиля. Если создание движков занимает больше, чем вызов конструктора, переместите его в статическую функцию конструктора.
class Engine {
private final int x;
private final int y;
Engine(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Car {
private final Engine engine;
public Car(int x, int y) {
this(new Engine(x, y));
}
Car(Engine engine) {
this.engine = engine;
}
}
public class FastEngine extends Engine {
private final double a;
private final double b;
FastEngine(int x, int y, double a, double b) {
super(x, y);
this.a = a;
this.b = b;
}
}
public class FastCar extends Car {
public FastCar(int x, int y, double a, double b) {
super(new FastEngine(x, y, a, b));
}
}
Я опишу ответ для Вашего конкретного вопроса, но тот же подход относится к другим режимам также.
Необходимо будет изменить режим процессора путем изменения битов режима в CPSR к системному режиму. Это предоставит Вам доступ к SP/LR непривилегированного режима (R13 и R14). Помните, что системный режим привилегирован, но его R13 и R14 совпадают с непривилегированным режимом R13 и R14.
После того как Вы находитесь в системном режиме, считайте R13 и R14 и поместите их, где Вы хотите. Затем просто переключите биты режима назад на Ваш предыдущий режим (я полагаю, что это было привилегированным режимом в Вашем примере), и Вы хороши для движения.
Обратите внимание, что мы не переключались от супервизора до непривилегированного режима. Если бы Вы переключились от супервизора до пользователя, то Вы не могли бы возвратиться к привилегированному режиму. (Иначе не было бы никакой защиты от пользовательского кода, наращивающего полномочие). Вот почему мы использовали системный режим - системный режим привилегирован, но регистры совпадают с непривилегированным режимом.
Можно переключиться между любым из привилегированных режимов по желанию путем управления битами режима в CPSR. Я думаю, что они - более низкие 5 битов? Я нахожусь на дороге и не имею информации в кончиках пальцев. Иначе я предоставил бы Вам ассемблерный код для того, что я описал выше. На самом деле, если Вы хотите поместить некоторые волосы на грудь, взять то, что я дал Вам выше, реализую его, тестирую его и отправляю его назад здесь.:-D
(Одна вещь, которую я должен добавить для "общего случая" (Ваш очень конкретен) - можно исследовать SPSR для наблюдения, "куда Вы произошли из" - и используйте это для определения, на какой режим необходимо переключиться.)
Между прочим, я просто сделал это недавно для одного из моих клиентов.... маленький мир, я предполагаю.
Я обнаружил лучший путь: -
При выполнении STM, если r15 не является одним из операндов затем, ^ предоставляет доступ к регистрам непривилегированного режима. Однако автопостепенное увеличение, кажется, не работает в рамках инструкции, и NOP требуется впоследствии, если Вы хотите получить доступ к банку регистра.
Что-то как
stmfd r13, {r13-r14}^ ;store r13 and r14 usermode
nop
sub r13, r13, #8 ;update stack pointer