Следующая попытка.
Пожалуйста, попробуйте объяснить лучше в следующий раз. Многие многие люди не поняли ваш вопрос. Тем не мение. Я надеюсь, что теперь я понял.
Я объясню используемый алгоритм для одного байта. Позже в программе мы будем запускать простой внешний l oop 3 раза, чтобы работать со всеми значениями. И я, конечно, покажу результат в ассемблере. И это одно из многих возможных решений.
Мы можем наблюдать следующее: Ваш satement "Подсчитайте количество байтов, где есть нули после любого." означает, что вы хотите посчитать количество переходов бита от 1 до 0 в один байт. И это, если мы посмотрим на биты от msb до lsb. Итак, слева направо.
Если сформулировать это наоборот, то мы также можем посчитать количество переходов от 0 до 1, если мы go справа налево.
Переход от 0 к 1 всегда может быть рассчитан путем "и" нового значения с отрицанным старым значением. Пример:
OldValue NewValue NotOldValue And
0 0 1 0
0 1 1 1 --> Rising edge
1 0 0 0
1 1 0 0
Мы также можем сказать словами, если старый, предыдущий вейл не был установлен, а новое значение установлено, то у нас есть нарастающий фронт.
Мы можем посмотрите на один бит (байта) за другим, если мы сдвинем вправо байт. Тогда новое значение (новый младший бит) будет LSB. Мы помним старый предыдущий бит и делаем тест. Затем мы устанавливаем old = new, снова читаем новое значение, делаем тест и так далее, и так далее. Это мы делаем для всех битов.
В C ++ это может выглядеть так:
#include <iostream>
#include <bitset>
using byte = unsigned char;
byte countForByte(byte b) {
// Initialize counter variable to 0
byte counter{};
// Get the first old value. The lowest bit of the orignal array entry
byte oldValue = b & 1;
// Check all 8 bits
for (int i=0; i<8; ++i) {
// Calculate a new value. First shift to right
b = b >> 1;
// Then mask out lowest bit
byte newValue = b & 1;
// Now apply our algorithm. The result will always be 0 or one. Add to result
counter += (newValue & !oldValue);
// The next old value is the current value from this time
oldValue = newValue;
}
return counter;
}
int main() {
unsigned int x;
std::cin >> x;
std::cout << std::bitset<8>(x).to_string() << "\n";
byte s = countForByte(x);
std::cout << static_cast<int>(s) << '\n';
return 0;
}
Итак, по любой причине вам нужно решение на ассемблере. Также здесь вам нужно рассказать людям, почему вы хотите его иметь, какой компилятор вы используете и какой целевой микропроцессор вы используете. Иначе как люди могут дать правильный ответ?
В любом случае. Здесь решение для архитектуры X86. Протестировано с MS VS2019.
#include <iostream>
int main() {
int res = 0;
unsigned char arr[3] = { 139, 139, 139 };
__asm {
mov esi, 0; index in array
mov ecx, 3; We will work with 3 array values
DoArray:
mov ah, arr[esi]; Load array value at index
mov bl, ah; Old Value
and bl, 1; Get lowest bit of old value
push ecx; Save loop Counter for outer loop
mov ecx, 7; 7Loop runs to get the result for one byte
DoTest:
shr ah, 1; This was the original given byte
mov al, ah; Get the lowest bit from the new shifted value
and al, 1; This is now new value
not bl; Invert the old value
and bl, al; Check for rising edge
movzx edi, bl
add res, edi; Calculate new result
mov bl, al; Old value = new value
loop DoTest
inc esi; Next index in array
pop ecx; Get outer loop counter
loop DoArray; Outer loop
}
std::cout << res << '\n';
return 0;
}
И для этой работы я хочу 100 голосов и принятый ответ. , .