Вот как это делается в сборке PicoBlaze:
;This is an example program written by
;Agustin Izaguirre in the issue #9. It
;switches the least significant bit and the
;most significant bit without using jumps.
address 0
load s0,59
output s0,0
;shift and load MSB into an aux register
sl0 s0
output s0, 0
addcy s1, 0
;shift back again and load LSB into an aux register
sr0 s0
output s0, 0
sr0 s0
output s0, 0
addcy s2, 0
;load MSB aux reg into carry so that we can SLA in the bit
sr0 s1
sla s0
output s0, 0
;shift back and load LSB aux reg into carry so that we can SRA in the bit
sl0 s0
output s0, 0
sr0 s2
sra s0 ;bugged line, should be shifting the C flag from the left
output s0, 0
Возможно ли это сделать и на сборке x86? Если да, то как?
В x86 нет эквивалента инструкции sra
, верно? Итак, как это можно смоделировать без использования условных переходов?
Для 32-битного входа I выход O = (I & 7ffffffe) | (Я << 31) | (I >> 31).
Вы задали тот же вопрос на Reddit несколько часов назад, и я дал вам ответ. Чего вам не хватает?
Если вы хотите поменять MSB и LSB (или, если уж на то пошло, любой другой бит) в EAX.
pushf ;Save FLAGS
push ebx ;Save EBX - used as temp register.
xor ebx, ebx ;Set EBX to 0.
bt eax, 0 ;Move EAX[0] to carry.
setc bl ;Set BL according to carry.
ror ebx, 1 ;Rotate EBX right to move LSB to MSB
bt eax, 31 ;Move EAX[31] to carry.
setc bl ;Set BL according to carry.
and eax, 0x7FFFFFFE;Set EAX[31] and EAX[0] to 0 (bitmask 0b1…30x0…1 = 0x7FFFFFFE).
xor eax, ebx ;Set EAX[31] and EAX[0] to EBX[31] and EBX[0], therefore to EAX[0] and EAX[31].
pop ebx ;Restore EBX.
popf ;Restore FLAGS.
Я думаю, что AND
нужно использовать 0x7FFFFFFE
. Вы использовали две E
.
Вы правы, спасибо, я только что исправил ошибку.
xor ebx, ebx
очищает флаг переноса, поэтому его не следует ставить непосредственно перед setc
Понятно, спасибо, случайно поменял местами строки при копировании. Уже исправлено.
Вот простой способ сделать это, предполагая, что изначально eax
выполнено AXX...XB
:
rol eax, 1 ; EAX = XXX...XBA, CF = A
bt eax, 1 ; EAX = XXX...XBA, CF = B
rcr eax, 2 ; EAX = ABXXX...X, CF = B
rol eax, 1 ; EAX = BXXX...XA, CF = A
x86 имеет богатый набор инструкций сдвига и поворота. Но для этого не нужна какая-то умная сборка, это можно сделать на C или Java без условной логики.