РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты в разделе Номер выпуска: | 1635 | Дата выхода: | 23.11.2016, 18:45 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 31 / 13 | Вопросов / ответов: | 1 / 1 | Консультация # 190021: Здравствуйте! Прошу помощи в следующем вопросе: Как можно проще и быстрее, пожалуйста, помогите... с комментариями , пожалуйста, не понятно... Тема Использование операторов сравнения (cmp), условных(Jxx), безусловных (JMP) переходов и циклов (LOOOP). Задание из двух частей. В первом задании необходимо подсчитать количество <... Консультация # 190021: Здравствуйте! Прошу помощи в следующем вопросе: Как можно проще и быстрее, пожалуйста, помогите... с комментариями , пожалуйста, не понятно... Тема Использование операторов сравнения (cmp), условных(Jxx), безусловных (JMP) переходов и циклов (LOOOP).
Задание из двух частей. В первом задании необходимо подсчитать количество чисел, соответствующих определенному условию на некотором числовом промежутке. Во втором задании требуется модифицировать свою программу так, чтобы найти и вывести на экран двухсотое число или пару чисел соответствующих заданному условию. Если таких чисел меньше двухсот, то вывести об этом сообщение на экран. На промежутке от 1 до 100 000 Подсчитать количество таких чисел X, что (Х+Х-1)div500 - простое число Ответ вывести на экран
Дата отправки: 13.11.2016, 18:34 Вопрос задал: EccoVIP (Посетитель) Всего ответов: 1 Страница онлайн-консультации » Консультирует Лысков Игорь Витальевич (Старший модератор): Здравствуйте, EccoVIP! Вот программа, решающая следующую задачу: для всех чисел Х из интервала 1:100000 находим частное от деления (Х+Х-1)/500 и проверяем его на простоту. Если простое, то считаем найденные числа. Простота проверяется делением данного числа на все числа от 3 до √Х. Четные числа отбрасываются сразу проверкой младшего бита на 0 Одновременно ищется 200-е число Х, удовлетворяющее условию (Х+Х-1)/500 - простое Вывод числа делается последовательным делением числа на 10, сохранением остатка в стеке с последующим выводом символов-цифр в обратном порядке
.model small ;модель памяти .386 ;будем использовать 32-битные регистры и команды сопроцессора MINNUM equ 1 ;начинаем счет с 1 MAXNUM equ 100000 ;до 100000 DIVNUM equ 500 ;делим на 500 .stack 200h .data sNumbersCount db "Numbers count = $" sNumber200 db "Number #200 = $" sCountLess200 db "Numbers count < 200", 0dh, 0ah, '$' temp dd ? ;здесь будет верхняя граница проверки на простое number200 dd ? ;200-е число, удовлетворяющее условию .code start: mov ax, @data ;настроим сегментный регистр данных на сегмент данных mov ds, ax call CalcSimples ;считаем простые числа ;выводим результат lea dx, sNumbersCount ;поясняющая строка mov eax, ebx ;количество чисел, удовлетворяющих условию call PrintData ;выводим cmp ebx, 200 ;сравним количество найденных чисел с 200 jb print_less_200 ;меньше - просто выводим сообщение ;выводим 200-е число lea dx, sNumber200 ;поясняющая строка mov eax, number200 ;само число call PrintData ;выводим jmp wait_key ;наожидание нажатия на клавишу print_less_200: ;чисел меньше 200 lea dx, sCountLess200 mov ah, 9 int 21h wait_key: mov ah, 0 ;ждем нажатие на клавишу int 16h mov ax,4c00h ;завершаем программу int 21h CalcSimples proc ;поиск чисел mov esi, DIVNUM ;делитель 500 xor ebx, ebx ;счетчик чисел mov edi, MINNUM ;X, начинаем с MINNUM=1 mov ecx, MAXNUM ;счетчик цикла = MAXNUM=100000 simple_loop: ;цикл поиска lea eax, [edi*2-1] ;eax = X+X-1 xor edx, edx ;подготавливаемся к делению idiv esi ;edx:eax / esi cmp eax, 2 ;рассматриваем частное от деления, отсеем числа меньшие 4 jb simple_next ;полученные числа, меньшие 2, игнорируем je simple_found ;= 2 считаем простыми cmp eax, 3 je simple_found ;= 3 также считаем простыми ;числа >= 4 анализируем на простоту push edi ;сохраним текущее число edi=X (EDI используется в процедуре) call simple ;проверяем на простоту, результат в флаге C, 1/0 - простое/непростое pop edi simple_add: adc ebx, 0 ;добавляем флаг С к счетчику найденных чисел cmp ebx, 200 ;найдем 200-е число jne simple_next mov number200, edi ;сохраним значение 200-го числа X, удовлетворяющее условию simple_next: inc edi ;следующее число Х loop simple_loop ;на продолжение цикла ret simple_found: ;явное указание, что число простое stc ;С=1 jmp simple_add ;на суммирование CalcSimples endp ;анализ на простоту числа eax путем деления на все нечетные числа, ;начиная с 3, и заканчивая корню квадратному из числа simple proc test eax, 1 ;отсеем четные числа по младшему биту je simple_no ;четные числа - непростые! mov edi, eax ;сохраним число ;найдем максимальное число, до которого будем делить ;его найдем, как корень квадратный из нашего числа mov temp, eax ;сохраним в памяти fild temp ;загрузим в сопроцессор fsqrt ;посчитаем корень fistp temp ;и извлечем обратно в память, с округлением до ближайшего целого mov ebp, 3 ;начальное значение делителя = 3 simple_cmp: ;цикла проверки на простоту cmp ebp, temp ;проверим, прошли ли крайнее значение jbe simple_continue ;нет - на продолжение проверки stc ;да - прошли все, значит число простое ret simple_continue: ;анализируем на простоту делением и проверкой остатка на 0 mov eax, edi ;наше число xor edx, edx ;подготавиваемся к делению idiv ebp ;edx:eax / ebp test edx, edx ;проверяем остаток на 0 jne simple_inc ;не ноль - на следующий делитель simple_no: clc ;разделилось нацело - число непростое! ret simple_inc: add ebp, 2 ;следующий делитель jmp simple_cmp ;на проверку выхода из анализа simple endp PrintData proc ;вывод сообщения push eax ;сохраним выводимое число mov ah, 9 ;выведем строку, адрес в dx int 21h pop eax ;наше число ;сформируем цифры числа в стеке xor cx, cx ;счетчик цифр mov esi, 10 ;будем делить на 10 digits_loop: xor edx, edx ;готовимся к делению div esi ;EDX:EAX / ESI push dx ;сохраним остаток (очередную цифру) в стеке inc cx ;считаем test eax, eax ;есть еще? jne digits_loop ;на продолжение ;выведем число mov ah, 2 ;функция вывода символа из dl print_loop: pop dx ;извлекаем очередную цифру из стека (в обратном порядке) or dl, '0' ;делаем из числа символ int 21h ;выводим loop print_loop ;по всем цифрам mov dl, 0dh ;перейдем на новую строку int 21h mov dl, 0ah int 21h ret PrintData endp end start ;конец программы с точкой входа  | Консультировал: Лысков Игорь Витальевич (Старший модератор) Дата отправки: 17.11.2016, 13:17 5 нет комментария ----- Дата оценки: 17.11.2016, 15:18 | Рейтинг ответа: +1 |
Оценить выпуск | Задать вопрос экспертам главная страница | стать участником | получить консультацию техническая поддержка Дорогой читатель! Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно! МЫ РАБОТАЕМ ДЛЯ ВАС! |
Комментариев нет:
Отправить комментарий