Цитата:
Сообщение от 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;