Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //https://vk.com/evgenykravchenko0
- ___ ___ ___
- / /\ ___ / /\ / /\
- / /:/_ /__/\ / /:/_ / /:/_
- / /:/ /\ \ \:\ / /:/ /\ / /:/ /\
- / /:/ /:/_ \ \:\ / /:/_/::\ / /:/ /:/_
- /__/:/ /:/ /\ ___ \__\:\ /__/:/__\/\:\ /__/:/ /:/ /\
- \ \:\/:/ /:/ /__/\ | |:| \ \:\ /~~/:/ \ \:\/:/ /:/
- \ \::/ /:/ \ \:\| |:| \ \:\ /:/ \ \::/ /:/
- \ \:\/:/ \ \:\__|:| \ \:\/:/ \ \:\/:/
- \ \::/ \__\::::/ \ \::/ \ \::/
- \__\/ ~~~~ \__\/ \__\/
- ___
- /__/\ ___ ___
- \ \:\ / /\ / /\
- \ \:\ / /:/ / /:/
- _____\__\:\ /__/::\ /__/::\
- /__/::::::::\ \__\/\:\__ \__\/\:\__
- \ \:\~~\~~\/ \ \:\/\ \ \:\/\
- \ \:\ ~~~ \__\::/ \__\::/
- \ \:\ /__/:/ /__/:/
- \ \:\ \__\/ \__\/
- \__\/
- #include "pch.h"
- #include <stdio.h>
- #include <locale.h>
- #include <cstdlib>
- int main()
- {
- setlocale(LC_ALL, "rus");
- short number = 0; // Используем short, т.к. его размер два байта
- short result = 0; // Используем short, т.к. его размер два байта
- printf_s("Enter number: \n");
- scanf_s("%hi", &number);
- _asm
- {
- mov ax, number // Записываем в ax значение переменной number. ax тоже размером 2 байта(15..0 биты)
- xor bx, bx // Обнуляем bx с помощью логической операции "искл. ИЛИ" размер тоже 2 байта(15..0 биты)
- // В bx будем записывать ответ(поэтому и обнуляем)
- xor si, si // Обнуляем регистр общего назначения
- cmp ax, 0 // Сравниваем ax с 0, чтобы не пробегать весь цикл
- jz exit // Если ax будет равен операнду справа в cmp (то есть 0), то будет прыжок на метку exit
- mov cx, 16 // Организуем счетчик для цикла count_units(16, т.к. 16 бит нужно пройти)
- count_units : // Метка для цикла(Цикл считает кол-во единиц в заданном числе)
- shr ax, 1 // Исп. логический сдвиг вправо, где ax(число в котором будем сдвигать биты)
- // а 1(на сколько будем сдвигать).Если снеслась крайний бит со значением 1, то CF=1
- // ПРИМЕР: 1101 сдвинули вправо и стало 0110 (CF=1, т.к. единица ушла за границы записи)
- // С каждым сдвигом CF меняется (если ушел ноль, то CF=0)
- // Каждый сдвиг с другой стороны всегда будет смещаться 0
- jnc next // Если CF=0, то переход на метку next(чтобы пропустить шаг и не прибавлять 1 к счетчику)
- // Если CF=1, то мы встретили единицу в записи числа
- add si, 1 // Значит прибавляем к si единицу
- next : // Метка для прыжка
- loop count_units // (loop уменьшает cx на 1) если cx = 0, то выход из цикла
- xor cx, cx // Обнуляем cx для следующего цикла с помощью xor
- // В цикле ниже мы должны будем сдвинуть влево и прибавить 1 столько раз, сколько в si 1-иц
- mov cx, si // Проматывать будем столько раз , сколько мы подсчитали единиц в предыдущем цикле
- create_result : // Метка цикла
- shl bx, 1 // Логический сдвиг уже влево(работает так же как shr , только влево
- // ПРИМЕР: 1101 сдвинули влево и стало 1010 (CF=1,т.к. единица ушла за границы записи)
- add bx, 1 // Прибавляем 1 к числу(Ведь нам нужны единицы сначала, а потом нули)
- loop create_result // (loop уменьшает cx на 1) если cx = 0, то выход из цикла
- exit : // Метка exit
- mov result, bx // Записываем результат в result
- }
- printf_s("Result is: %hi \n", result);
- system("pause");
- return 0;
- }
- ===========================================================================================================================
- |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- ===========================================================================================================================
- ПРИМЕР ВЫПОЛНЕНИЯ НА 4 БИТАХ(ЧТОБЫ ДОЛГО НЕ ПИСАТЬ, СУТЬ ВСЯ ТАКАЯ ЖЕ) ПРОСТО ТАК МНЕ ПИСАТЬ МЕНЬШЕ БУДЕТ
- ===========================================================================================================================
- ПОСТУПИЛО ЧИСЛО ПУСТЬ 5
- 5 В ДВОИЧНОЙ ЭТО 0101
- (У МЕНЯ ЧИСЛО В 4 БИТА ПОЭТОМУ Я ПРОЙДУСЬ 4 РАЗА, ЧТОБЫ ПРОВЕРИТЬ КАЖДЫЙ БИТ)
- !!!В ЗАДАНИИ 16 БИТ И ТАМ НУЖНО 16 РАЗ ПРОЙТИСЬ В ПЕРВОМ ЦИКЛЕ) ВСЕ ЛОГИЧНО
- СНАЧАЛА МЫ СЧИТАЕМ КОЛ-ВО ЕДИНИЦ
- СДВИГАЕМ 0010 (CF = 1) тогда si увеличиваем на 1
- СДВИГАЕМ 0001 (CF = 0) переходим по метке, чтобы пропустить увеличение si на 1
- СДВИГАЕМ 0000 (CF = 1) тогда si увеличиваем на 1
- СДВИГАЕМ 0001 (CF = 0) переходим по метке, чтобы пропустить увеличение si на 1
- ТЕПЕРЬ Я ПЕРЕХОЖУ НА ВТОРОЙ ЦИКЛ si=2 ПОЭТОМУ В cx ЗАПИСЫВАЕМ si(ТО ЕСТЬ 2)
- bx у нас все 0( Т.К. МЫ ЕГО ОБНУЛИЛИ В САМОМ НАЧАЛЕ)
- СДВИГАЮ 0000 (ПО СУТИ НАЧАЛО НЕ ИГРАЕТ РОЛИ , НО ПО ДРУГОМУ НИКАК)
- ПРИБАВЛЯЮ 1 ( БУДЕТ 0001)
- СДВИГАЮ 0010
- ПРИБАВЛЯЮ 1 (БУДЕТ 0011)
- 0011 - НАШ ОТВЕТ
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement