Я хочу получить значение флага переноса после выполнения сдвига битов.
Rust имеет стабильные функции, которые проверяют переполнение следующим образом:
pub fn add_with_carry(foo : &mut u8, bar : u8, cf : &mut u8) {
let(result, overflow) = foo.overflowing_add(bar);
*foo = result;
*cf = overflow as u8;
}
, который генерирует сборку следующим образом:
example::add_with_carry:
add byte ptr [rdi], sil
setb byte ptr [rdx]
ret
однако overflowing_shr
возвращает значение true, только если значение смещено на его размер или более. Я забочусь только о младшем значащем бите, который будет храниться в CF, в настоящее время лучшее, что я придумаю, это:
pub fn shr(foo : &mut u8, cf : &mut u8) {
*cf = *foo & 1;
*foo >>=1
}
однако это несколько менее эффективно:
example::shr:
mov al, byte ptr [rdi]
and al, 1
mov byte ptr [rsi], al
shr byte ptr [rdi]
ret
Я бы предпочел что-то вроде:
example::shr:
shr byte ptr [rdi]
setc byte ptr [rdx]
ret
Похоже, что для получения CF нет ничего общего, и встроенная сборка в настоящий момент не стабильна.