Последовательность нулей и единиц

216
09 февраля 2020, 13:30

В двухбайтной ячейке памяти записана последовательность нулей и единиц. С помощью битовых операций переставьте биты так чтобы сначала шли все единицы, а затем все нули. (реализуется, как ассемблерные вставки в С++)

Реализовал код уже на ассемблере:

_asm
    {
        mov bx, 0
        mov ax, i
        mov cx, 16 //Счетчик
        m1: //цикл
            shl ax, 1 //Логический сдвиг влево на одну клетку
            adc bx, 0
        loop m1
        cmp bx, 0; //Если единиц нет
        jz  m2 
        mov cx, bx
        m0 :
            shl ax, 1 //Логический сдвиг влево на одну клетку
            add ax, 1
        loop m0
        m2 :
            mov s, ax
    }

Проблема в том, что также нужна часть на С++. А с этим как раз и возникает проблема, ибо непонятно, как вводить эту последовательность нулей и единиц (точнее, какой тип указать для них). Также пока непонятно, как реализовать программу для сдвига всех единиц и нулей на С++.

Answer 1

Код:

#include <iostream>
#include <bitset>
int main()
{
    unsigned short ref = 0x0F0F, res = 0x0000;
    asm volatile (
        "mov $0, %%bx       \n"
        "mov %1, %%ax       \n"
        "mov $16, %%cx      \n"
        "m1:                \n"
        "   shl $1, %%ax    \n"
        "   adc $0, %%bx    \n"
        "   dec %%cx        \n"
        "   jnz m1          \n"
        "cmp $0, %%bx       \n"
        "jz m2              \n"
        "mov %%bx, %%cx     \n"
        "m0:                \n"
        "   shl $1, %%ax    \n"
        "   add $1, %%ax    \n"
        "   dec %%cx        \n"
        "   jnz m0          \n"
        "m2:                \n"
        "   xchg %%al, %%ah \n"
        "   mov %%ax, %0    \n"
        :"=r"(res)   // выходные параметры (output operands) 
        :"r"(ref)    // входные параметры (input operands)
        :);
    std::bitset<16> ref_bs { ref }, res_bs { res };
    std::cout << "ref = (" << ref << ") " << ref_bs << ' '
              << "res = (" << res << ") " << res_bs << '\n';
    return 0;
}

Я немного подправил Ваш код:

xchg %%al, %%ah

, в противном случае единицы находились в %al, а не %ah.

UPD.: я обнаружил, что я обманул Вас вчера - xchg сработал только потому, что я подобрал "удобное" число. Правильное решение заключается в следующем - вместо того, чтобы делать сдвиг влево и добавлять единицу:

"   shl $1, %%ax    \n"
"   add $1, %%ax    \n"

, мы будем делать сдвиг вправо и добавлять 0x8000:

"   shr $1, %%ax        \n"
"   add $0x8000, %%ax   \n"

Обновленный пример в wandbox.

READ ALSO
Динамические массивы в stl

Динамические массивы в stl

Хочу создать квадратную матрицу с помощью stl и чтобы пользователь сам заполнял массивПока код такой:

241
Cделать меню адаптивным в карусельке Bootstrap

Cделать меню адаптивным в карусельке Bootstrap

Нужно сделать меню и текст адаптивным и сохранить в том же порядке что он сейчас( текст ровно между кнопок скрола и меню именно вверху в карусельке),...

284
Криво загружается меню на сайте

Криво загружается меню на сайте

Проблема в том, что при загрузке сайта на некоторое время до полной загрузки меню без стилей появляется в верхнем левом углуВ чем могут быть...

300