Это вопрос, с которым я столкнулся во время интервью и для которого я не нашел решения, поэтому я попытался решить его сам.
Мы можем использовать здесь псевдокод - это не обязательно должен быть формальный код.
Вопрос в том, чтобы получить абсолютную разницу беззнаковых входов:
Предположим, ваш язык ассемблера включает ТОЛЬКО следующие инструкции:
inc
,dec
,jnz
иhalt
(halt
= остановить выполнение).Задача:
A
иB
- это регистры, в которых хранятся неотрицательные значения. Программа должна вычислить значение|A-B|
и найти результат вC
. Кроме того, язык содержит регистрыC
,D
, ...,Z
, которые, как вы можете предположить, обнуляются при запуске программы.
Это моя попытка, где моя основная идея - уменьшить оба регистра до тех пор, пока один из них не станет равным нулю, а затем переместить значение другого регистра на C
:
// zero case handling
dec a
inc a
jnz a_pre_loop_not_zero // a != 0
// a == 0, check if b == 0
dec b
inc b
jnz move_b_to_c // a == 0, b !=0
// a == 0 , b == 0 -> c needs to be 0
halt
a_pre_loop_not_zero:
dec b
inc b
jnz main_loop // a != 0, b != 0
// a != 0 , b == 0
move_a_to_c:
inc c
dec a
jnz move_a_to_c
halt
// a,b != 0
main_loop:
dec b
jnz b_not_zero // b!=0
// b became zero before a -> a contains result+1 now
dec a
jnz move_a_to_c
halt // if a == 0 now -> a == b -> c needs to be 0
b_not_zero:
dec a
jnz main_loop // a != 0
// a became zero before b -> b contains the result now
move_b_to_c:
inc c
dec b
jnz move_b_to_c
halt
Теперь я думаю, что это работает, но выглядит очень грязным.
Чтобы быть более конкретным, я думаю, что обработка нулевого регистра может быть выполнена более чистым способом, и, возможно, мы можем даже рассмотреть это в основном цикле (без проверки это в коде до цикла).
Кроме того, я не использовал тот факт, что регистры C
, D
, ..., Z
инициализируются значением 0 и могут быть использованы - что заставляет меня подозревать, что, возможно, есть лучший способ .
Есть ли лучшее решение этой проблемы?
do { if(--a == 0) break; } while(--b);
Но мы можем синтезировать JZ из JNZ по фиктивному INC / JNZ регистра, который был равен нулю в начале цикла. Или inc / dec / jnz ненулевого регистра. - person Peter Cordes   schedule 01.06.2020