Показать сообщение отдельно
  #8  
Старый 08.10.2014, 13:32
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от icWasya
Value при вызове функции находится в паре регистров, в EDX - старшая часть, в EAX - младшая.
Вот именно поэтому и будет работать. Если мы нашли значащий бит в старшей части, младшая нам уже не нужна. А при нулевом значении EDX операция BSR не изменяет EAX, хотя в доке написано, что поведение в этом случае не определено.

Цитата:
Сообщение от icWasya
5) SHL EAX, 1 - зачам-то умножаем на два, хотя надо прибавить 32
А вот за дельное замечение спасибо. Как-то упустил этот момент, а код не отлаживал.

Попутно выяснилось также, что Delphi за каким-то чертом создает стековый кадр в этой простой функции, и голый RET не работает, нужно восстановление EBP. Чтобы не завязываться на причуды Delphi, пришлось добавить второй переход:
Код:
function MostSignificantBit(Value: Int64): LongInt; overload;
asm
        BSR EAX, EDX // неопределенное поведение
        JZ @@lo
        ADD EAX, 32
        JMP @@exit
@@lo:
        BSR EAX, EAX
@@exit:
end;

function MostSignificantBit(Value: Int64): LongInt; overload;
asm
        BSR EDX, EDX  // безопасно во всех смыслах
        JZ @@lo
        MOV EAX, 32
        ADD EAX, EDX
        JMP @@exit
@@lo:
        BSR EAX, EAX
@@exit:
end;
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием