|
|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Sashka Yackubtchick 2:5054/29.54 04 Dec 2001 19:53:50 To : Andrey Dashkovsky Subject : максимум двух чисел без сравнения -------------------------------------------------------------------------------- 28 Nov 01 22:26, Andrey Dashkovsky писАл(а) к Kostya Sudilovsky: KS>> Так ведь сказано: не используя условного оператора KS>> abs(x) по определению x если x>=0 иначе -x KS>> PS простите мне мне мою занудность :) AD> cwd ; Расширение 2-х байтового числа до 4-х байтового, путём заполнения dx AD> xor ax,dx AD> inc ax AD> Эти 3 команды асма находят модуль целого 2-х байтового числа в регистре AD> ax. Вот только насчёт cwd - неуверен, под рукой справочника нету, но кто AD> на асме пишет без труда вспомнит как комманда называется. Hет, Андрей :) Данный код не получит модуль а просто поменяет знак числа по согласованию в дополнительном коде. Чтобы получить модуль код должен быть следующим: mov ax,number cwd xor ax,dx sub ax,dx ;! Я постараюсь объяснить так чтобы интересно было не только тем, кто пишет на ассемблере но и программистам других языков и просто интересующимся конкретной математикой. Информация необходимая для понимания работы (далее я буду ссылаться на неё в скобках) 1. CWD -+--+--+--+-- Единственная "особая" команда в этом коде, поэтому думаю важно пояснить, что она делает. Это действительно расширение слова до двойного слова, где старшая часть вновь образованого двойного слова помещается dx а младшая в ax. Hо что важно для нас так то, что это ЗHАКОВОЕ расширение. То есть если ax положительный в dx окажется 0 (все биты установлены в 0) а если он отричательный то в dx окажется -1(все биты установлены в 1(см. в эхе разъяснения по дополнительному коду)) Именно для этого и нужна нам эта команда чтобы в зависимости от знака получить в dx либо все биты установленные в 0 либо все биты установленые в 1 2. Особенности XOR числа на 11111111 или 00000000 -+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-- XOR числа на - 1 (все биты поставлены) приведёт к инвертированию всех битов числа Важно что это же делает оператор NOT. XOR числа на 0 (все биты сброшены) приведёт к тому что число неизменится Для нашего случая получается, что case negative: если ax отрицательный xor ax,dx приведёт к not ax case positive: если ax положительный ax неизменится 3. Изменение знака. -+--+--+--+--+--+--+--+--+--+--+--+- Изменение знака в дополнительном коде можно представить как (not число) + 1 Пример - 1 = 1111 1111 NOT 1111 1111 = 0000 0000 0000 0000 +1 = 1 1 = 0000 0001 NOT 0000 0001 = 1111 1110 1111 1110 +1 = 1111 1111 (-1) 4. - - = + ; a - 0 = a -+--+--+--+--+--+--+--+--+--- В зависимости от того был ли у нас ax положительным из него вычтется в конце либо - 1 либо 0 Однако минус - 1 = +1 (в случае если ax был негативным) а ax - 0 = ax (в случае если он был позитивным) Теперь соберём это всё вместе на примерах случая когда ax положительный и случая когда он отрицательный: Положительный: ============== cwd ;dx = 0 (1) xor ax,dx ; xor ax,0 = ax (2) sub ax,dx ;ax - 0 = ax (4) Результат - ни на одном шаге ax не изменился Отрицательный: ============== cwd ; dx = - 1 (11111111) (1) xor ax,dx ; ax = not (ax) (2) sub ax,dx ; ax = not(ax) - (-1) = (not (ax) ) +1 = negate ax (3);(4) Последняя комментарий явно показывает что произошло изменение знака по правилам для дополнительного кода (NOT(число)) + 1 И при сравнении выполнения в двух случаях очевидно, что это может произойти только если ax был отрицательным. Пока! Sashka, The Svin. --- GoldED/W32 3.00.Beta1+ * Origin: Svin, Perm, Russia (2:5054/29.54) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/33843c0d2443.html, оценка из 5, голосов 10
|