Преобразовать c в сборку с предикатной инструкцией
Я хочу преобразовать этот код в сборку, используя предикатную инструкцию
If (A>B){
C=A;
D=B;
E=0
}
else{
C=B;
}
Это правильно или как я могу использовать прыжок?
cmp R1,R2; considering B is assigned to R2 and A assigned to R1
movlf R3,R1;R3 assign to C
mov R4,R2;R4 assign to D
mov R5,0; R5 assign to E
movlt R3,R2
1 ответ
ВНИМАНИЕ: Ответ для новичков. Может утомить опытных пользователей до смерти.
Я не уверен, что вы неправильно использовали терминологию или действительно хотите использовать предикатные инструкции1.
В последнем случае, используя предикацию ARM v6 в качестве учебного примера (и наследуя ваши предпосылки об использовании регистров), сборка просто
;r1 = A r2 = B r3 = C r4 = D r5 = E
;
;A, B unsigned | ;A, B signed
|
cmp r1, r2 | cmp r1, r2
|
movhi r3, r1 | movgt r3, r1
movhi r4, r2 | movgt r4, r2
movhi r5, #0 | movgt r5, #0
|
movls r3, r2 | movle r3, r2
Здесь я дал две версии, основанные на признаке задействованных переменных.
movhi
значит двигаться, если выше. movls
значит двигаться, если ниже или то же самое.movgt
значит двигаться, если больше. movle
значит двигаться, если меньше или равно.
Они означают одно и то же арифметическое сравнение, просто последний использует правильные флаги для чисел со знаком.
Я сгруппировал инструкции, поэтому легко идентифицировать блоки if-then и else.
Обратите внимание, что инструкции в одном и том же блоке имеют одинаковый суффикс (например, hi
а также ls
).
Что на самом деле делает этот код конструкцией if-then-else, а не чем-то еще, так это тем, что условия hi
-ls
а также gt
-le
являются взаимоисключающими (только одна из двух может быть правдой).
Таким образом, только один блок инструкций может быть выполнен.
Использование не взаимоисключающих условий приводит к появлению нескольких операторов if-then-else.
Если вы неправильно использовали терминологию и на самом деле хотели просто реализовать условный оператор (или выбор), то есть if-then-else, тогда обычный подход - это условный переход2, как уже показал Нутан.
Вот чуть более читаемая версия:
cmp r1, r2
bls _A_less_same_B
mov r3, r1
mov r4, r2
eor r5, r5, r5
b _end_if
_A_less_same_B:
mov r3, r2
_end_if:
На вас лежит бремя преобразования этого кода для работы со знаковыми целыми числами.
Причудливые слова, оканчивающиеся на двоеточие (:
) называются метками, они полезны для именования точек в коде (и данных).3.
Думайте об этом как о гибких номерах строк.
b
означает переход, после его выполнения следующая инструкция выбирается из метки (адреса), указанной как операнд (например, из _end_if
).bls
это просто предикат b
(bls
означает ветвь, если она меньше или такая же), обычно называемая условной ветвью.
Условные ветви аналогичны обычным ветвям, но их можно "игнорировать", если указанные условия не выполняются.
Условный переход считается выполненным, если выполняются условия и процессор выполняет переход, тем самым извлекая следующие инструкции из метки, указанной как операнд.
Говорят, что оно не выполняется, если условия не выполняются, и ЦП продолжает выполнение из инструкции после ветвления (поток программы падает).
"Условия" обычно означают установленные и очищенные флаги. Некоторая инструкция, как cmp
Установите и снимите эти флаги.
Другие инструкции, такие как bls
используйте эти флаги.
Флаги хранятся в выделенных регистрах (ps
в ARM), но есть архитектуры, особенно MIPS, которые не имеют регистра флагов.
Вы можете использовать свой палец, чтобы моделировать поток программы. Например, если A > B
поток выглядит следующим образом:
[Start Here]
¯¯¯¯+¯¯¯¯¯
cmp r1, r2 |
bls _A_less_same_B + [Branch not taken, fall through]
|
mov r3, r1 |
mov r4, r2 |
eor r5, r5, r5 |
|
b _end_if +--[Branch always taken]----+
|
_A_less_same_B: |
mov r3, r2 |
|
_end_if: +--[Land here]--------------+
|
V
Изгиб предназначен для изображения "перепрыгивания" кода, который мы хотим пропустить (иначе в данном случае).
Я не знаю, как выглядит ваш вопрос на ассемблере, поэтому я не могу помочь с написанием конкретных примеров.
Я бы не стал этого делать, так как чувствую, что этого общего объяснения достаточно, и в надежде, что такое отсутствие усилий с моей стороны подтолкнет вас к попыткам решить это упражнение самостоятельно.
Что является обязательным шагом на пути обучения.
1 Инструкция, которая извлекается, декодируется (возможно, тоже выдается), но выполняется только в том случае, если установлены или очищены определенные флаги.
2 Обратите внимание, что условных ветвей лучше избегать, если это возможно. В зависимости от целевой микроархитектуры может быть более оптимальный способ достижения того же результата. Это просто стоит отметить, не беспокойтесь об этом прямо сейчас.
3 На самом деле смещения, которые станут адресами.