17.11.2019, 12:34 [+3 UTC]
в нашей команде: 3 977 чел. | участники онлайн: 7 (рекорд: 21)

:: РЕГИСТРАЦИЯ

задать вопрос

все разделы

правила

новости

участники

доска почёта

форум

блоги

поиск

статистика

наш журнал

наши встречи

наша галерея

отзывы о нас

поддержка

руководство

Версия системы:
7.77 (31.05.2019)
JS-v.1.34 | CSS-v.3.35

Общие новости:
28.04.2019, 09:13

Форум:
16.11.2019, 20:23

Последний вопрос:
17.11.2019, 12:05
Всего: 150984

Последний ответ:
17.11.2019, 02:39
Всего: 259420

Последняя рассылка:
17.11.2019, 10:15

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
12.11.2018, 12:42 »
askolesnikov
Ответ с пояснением, применённого способа. Спасибо! [вопрос № 193826, ответ № 276858]
20.10.2017, 20:07 »
zuihin.c@mail.ru
Спасибо огромное! не знал как подступиться, выручили . [вопрос № 191508, ответ № 275392]
18.12.2011, 09:12 »
Посетитель - 385948
Спасибо огромное за помощь !!! [вопрос № 184839, ответ № 269198]

РАЗДЕЛ • Assembler

Создание программ на языке Assembler.

[администратор рассылки: Лысков Игорь Витальевич (Старший модератор)]

Лучшие эксперты в этом разделе

Коцюрбенко Алексей Владимирович
Статус: Модератор
Рейтинг: 1366
Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 565
solowey
Статус: Бакалавр
Рейтинг: 215

Перейти к консультации №:
 

Консультация онлайн # 190021
Раздел: • Assembler
Автор вопроса: EccoVIP (Посетитель)
Отправлена: 13.11.2016, 18:34
Поступило ответов: 1

Здравствуйте! Прошу помощи в следующем вопросе:
Как можно проще и быстрее, пожалуйста, помогите... с комментариями , пожалуйста, не понятно...
Тема
Использование операторов сравнения (cmp), условных(Jxx), безусловных (JMP) переходов и
циклов (LOOOP).


Задание из двух частей. В первом задании необходимо подсчитать количество
чисел, соответствующих определенному условию на некотором числовом промежутке.
Во втором задании требуется модифицировать свою программу так, чтобы найти и
вывести на экран двухсотое число или пару чисел соответствующих заданному
условию. Если таких чисел меньше двухсот, то вывести об этом сообщение на экран.
На промежутке от 1 до 100 000
Подсчитать количество таких чисел X, что (Х+Х-1)div500 - простое число
Ответ вывести на экран

Состояние: Консультация закрыта

Ответ # 274273 от Лысков Игорь Витальевич (Старший модератор)

Здравствуйте, EccoVIP!
Вот программа, решающая следующую задачу:
для всех чисел Х из интервала 1:100000 находим частное от деления (Х+Х-1)/500
и проверяем его на простоту. Если простое, то считаем найденные числа.
Простота проверяется делением данного числа на все числа от 3 до √Х.
Четные числа отбрасываются сразу проверкой младшего бита на 0
Одновременно ищется 200-е число Х, удовлетворяющее условию (Х+Х-1)/500 - простое
Вывод числа делается последовательным делением числа на 10, сохранением остатка в стеке
с последующим выводом символов-цифр в обратном порядке

Код (Assembler) :: выделить код
	.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

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 190021

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 1

= общий = | 14.11.2016, 11:55 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
EccoVIP:

Используем 16-битные регистры или 32-битные?

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

EccoVIP
Посетитель

ID: 400150

# 2

= общий = | 15.11.2016, 17:46 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

любые...

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 3

 +1 
 
= общий = | 15.11.2016, 18:37 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
EccoVIP:

(Х+Х-1)div500, как это понимать?
Х+Х-1 - число нечетное
После деления на 500 получаем частное и остаток. Остаток будет всегда (число нечетное).
Остаток отбрасываем, рассматриваем только частное. Так получается?
Но тогда придется рассматривать порядка 250 одинаковых чисел... Как-то непонятно зачем...

Да и вот это "двухсотое число или пару чисел соответствующих заданному условию" не совсем понятно.
Какая такая пара чисел имеется в виду?

Разъясните условие, как Вы его понимаете

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

EccoVIP
Посетитель

ID: 400150

# 4

= общий = | 15.11.2016, 21:40 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Лысков Игорь Витальевич
дело в том , что я сам и не понял, там такая неопределенность с заданием этим, елси можете помочь, помогите, пожалуйста по свой идеи....

EccoVIP
Посетитель

ID: 400150

# 5

= общий = | 15.11.2016, 21:42 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Исходные данные
Как работать с циклами описано в руководстве:
Index.html
в главе 3 в разделе циклы и условные переходы.
Метки необходимо объявлять так, как это делается в языке pascal.

-----
 Прикрепленный файл:  скачать (RAR) » [605 байт]

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 6

 +1 
 
= общий = | 15.11.2016, 23:21 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
EccoVIP:

Как работать с циклами и условными переходами, я знаю и так smile
Ладушки, завтра что-нибудь нарисую smile

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

EccoVIP
Посетитель

ID: 400150

# 7

= общий = | 17.11.2016, 15:18 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Лысков Игорь Витальевич
спасибо!

 

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

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.14370 сек.

© 2001-2019, Портал RFPRO.RU, Россия
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.77 от 31.05.2019
Версия JS: 1.34 | Версия CSS: 3.35