Вопрос № 177575:Доброго времени суток дорогие эксперты помогите решить две задачки, с которыми я не могу справится изза отсутствия опытности. 1) требуется написать программу для вычисления двух выражений с использованием макросов и процедур. Каж...
Вопрос № 177575:
Доброго времени суток дорогие эксперты
помогите решить две задачки, с которыми я не могу справится изза отсутствия опытности.
1) требуется написать программу для вычисления двух выражений с использованием макросов и процедур. Каждую переменную(x,y,z) описывать в отдельных сегментах данных:
a=(0.08cos^2(3x)-e^z)/((корень 5 степени из(log^2(по основанию 3 числа y)-z))+7z)
b=(корень 5 степени из(log^2(по основанию 3 числа y)-z)-5y+0.00006
2)Построить массив всех простых
чисел, не превышающих заданное число N. Результаты вы-вести на экран. Ввести с клавиатуры двоичное число в виде последовательности K двоичных цифр (k<8 ) и выдать на экран символ, которому соответствует эта последовательность.
Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, Юдин Евгений Сергеевич. Вот Вам первая программа. Все данные задаются в коде. Ничто не вводится/не выводится. Цель данной программы - работа с макро, разными сегментами и с сопроцессором
Код:
.386 ;необходимо для команды fcos sseg segment stack "stack" db 1024
dup (0) sseg ends
dsegX segment use16 para public 'data' x dd 1.5 dsegX ends
dsegY segment use16 para public 'data' y dd 5.6 dsegY ends
dsegZ segment use16 para public 'data' z dd 1.1 dsegZ ends
dseg segment use16 para public 'data' a dd ? b dd ? ;константы c8 dd 0.08 c3 dd 3. c5 dd 5. c6 dd 0.00006 c7 dd 7. dseg ends
;в st должно находить
ся xlog[2]y POWER MACRO fld st ;x*log[2]e->st(1) frndint ;округляем st до целого fsub st(1),st ;st(1)-=st fxch ;st(1)<->st f2xm1 ;st=(2 в степени st) - 1 fld1 ;1->st fadd ;st+=1 fscale ;exp = st * (2 в степени st(1)) fstp st(1) ;чтобы убрать значение из st(1) ENDM
;e^st ;st = z EXP MACRO fldl2e ;log(осн 2)e->st fmulp ;st(1)*log(осн 2)e->st POWER ;st=e^(st) ENDM
;(log[3]y-z)1/5 CALC_YZ MACRO yoff,zoff les bx,yoff ;address
y fld dword ptr es:[bx] ;y->st LOG3 ;st=log[3]y fld st ;st=st(1) fmulp ;st=log[3]y^2 les bx,zoff ;address z fsub dword ptr es:
[bx] ;st=log[3]y^2-z ;возведем в степень 1/5 fld1 ;1 fdiv c5 ;1/5 fxch ;st(1)<->st fyl2x ;st=st(1)*log[2]st POWER ;находим (log[3](y)^2-z)^(1/5) ENDM
cseg segment para use16 public 'code' assume cs:cseg, ss:sseg, ds:dseg start: mov ax,sseg mov ss,ax mov ax,dseg mov ds,ax
push dsegX ;в стек длинные адреса x push offset x push dsegY ;y push offset y push dsegZ ;z push offset z call calc_a ;получаем
в st ответ fstp a ; и сохраняем его в переменной
push dsegY ;y push offset y push dsegZ ;z push offset z call calc_b ;получаем в st ответ fstp b ; и сохраняем его в переменной
Вот вторая программа. Вводим число N<= 32000 и получаем требуемые простые числа по методу "решета Эратосфена&q
uot;
Код:
.286
cseg segment para public 'code' assume cs:cseg, ds:dseg, es:dseg start: mov ax, dseg mov ds, ax mov es, ax
;будем хранить "решето Эратосфена" в стеке, поэтому выделим ;достаточно места для данных (максимально 32000 значений) ;сам
сегмент будет размещен в конце, за сегментом данных ;изначально sp = 0 sub sp, 32000*2 ;максимум 32000 слов mov bp, sp ;bp - начало массива данных
repeat: ;если ошибка, то повторим запрос максимального числа call GetMax ;вводим макс число jnc num_ok ;ошибки нет jnz pr_err_max ;ошибка - переполнение, значение числа > 65536 ;ошибка - не число lea dx, ErrorNumMessage mov ah, 9 int 21h jmp repeat ;на п
овтор num_ok: jz exit ;пустая строка - на выход cmp ax, 32000 ;проверим, чтобы было <= 32000 jbe max_ok ;с макс числом все в порядке pr_err_max: ;число > 32000 lea dx, ErrorMaxMessage mov ah, 9 int 21h jmp repeat ;на повтор
max_ok: mov num, ax ;сохраним
call Eratosphen ;строим массив простых чисел ("решето Эратосфена")
mov cx, num ;максимальное
число dec cx ;учтем, что всего 0-num, т.е. num+1 штук, ;но храним на 2 меньше, т.е. всего получается num-1 штук xor si, si ;индекс SimpleShow: mov ax, [si+bp] ;очередное число test ax, ax ;проверим, простое? jz SimpleNext ;0 - составное call outNumber ;простое выводим SimpleNext: add si, 2 ;на следующее число loop SimpleShow
exit: mov ax,4c00h ;выход int 21h
GetMax proc ;вводим максимально
е число с проверкой на корректность lea dx, prompt mov ah, 9 int 21h ;подсказка
lea dx, max mov ah, 0ah int 21h ;вводим строку
;преобразуем строку в число xor di, di ;наше число lea si, string ;адрес строки GM_loop: lodsb ;очередной байт cmp al, 0dh ;проверим на последний 0dh je GM_end ;дошли до конца cmp al, '0' ;проверим на цифру jb GM_error cmp al, '9' ja GM_error push ax ;сохраним очередной разряд mov ax,
10 ;сдвинем предыдущие на 1 десятичный разряд mul di pop cx ;восстановим текущую цифру test dx, dx ;проверим на переполнение, т.е.число стало > 65536 jnz GM_max_error ;на ошибку переполнения and cx, 000fh ;'0'-'9' -> 0-9 add ax, cx ;добавляем текущий разряд mov di, ax ;и сохраним промежуточный результат jmp GM_loop ;по всем цифрам GM_end: mov ax, di ;результат test ax, ax ;проверим на пуст
ую строку (для 0 флаг Z будет установлен) clc ;ок ret GM_error: ;не число! xor ax, ax ;флаг Z установлен stc ;флаг C установлен ret GM_max_error: ;переполнение! or ax, 1 ;флаг Z сброшен stc ;флаг C установлен ret GetMax endp
Eratosphen proc ;построение "решета Эратосфена" ;заполним массив числами 2...max xor si, si ;индекс в массиве mov cx, num ;максимальное число mov ax, 2 ;начнем с 2 sub cx, ax ;на 2 меньше (0
и 1) shl cx, 1 ;cx - максимальное значение индекса store: mov [si+bp], ax ;сохраним inc ax ;следующее inc si ;индекс для следующего inc si cmp si, cx ;дошли до конца? jbe store ;собственно построение "решета Эратосфена" ;будем заменять нулями составные числа xor si, si ;индекс ErLoop: cmp si, cx ;сравним с максимальным значением ja ErRet mov ax, [si+bp] ;берем очередное число test ax, ax<
br> jz ErNext ;непростое обходим mov di, si ;текущий адрес shl ax, 1 ;адресуем слова ErClear: add di, ax ;добавляем зна
чение простого cmp di, cx ;проверим с максимальным ja ErNext mov word ptr [di+bp], 0 ;и отсеиваем составные (даже если уже было помечено) jmp ErClear ErNext: inc si ;на следующее число inc si jmp ErLoop ErRet: ret ;составные стали нулями! Eratosphen endp
outNumber proc ;вывод десятичного числа в виде строки, в конце один пробел push cx ;сохраним счетчик цикла (при выводе массива) mov bx, 10 ;десятичная система xor cx, cx ;счетчик цифр в числе
isDiv: xor dx,
dx ;делим число на 10 div bx push dx ;запоминаем в стеке остаток от деления inc cx ;считаем количество запоминаемых символов or ax, ax ;продолжаем пока АХ не равно 0 jnz isDiv
isOutNum: ;выводим из стека цифры в нужном порядке pop ax or al, 30h ;переводим цифру в символ ;выводим в режиме телетайпа ;эта функция аналогична mov ah,02 - int 21h ;только места меньше занимает int 29h ;повторяем выв
од в цикле loop isOutNum
mov al, 20h ;разделительный пробел int 29h pop cx ;восстановим счетчик ret OutNumber endp
cseg ends
dseg segment para public 'data' prompt db 'Enter max number: $' simples db 0ah,0dh,'Simples: $' ErrorNumMessage db 0ah,0dh,'Not number! Repeat$' ErrorMaxMessage db 0ah,0dh,'Number must be <= 32000! Repeat$' ;буфер для ввода строки max db 6 ;максимально возможная длина (+1 для
0dh) count db 0 ;реальная длина string db 6 dup (?);сама строка num dw 0 ;введенное число dseg ends
end start ;конец программы
И третья программа... Вывод осуществляем при помощи функции 0eh прерывания 10h BIOS, ввод с клавиатуры - с помощью прерывания 16h BIOS
Код:
.286
cseg segment para public 'code' assume cs:cseg, ds:dseg start: mov ax, dseg mov ds, ax
mov bh, 0 ;будем выводить в нулевую страницу, ;bh не меняется, поэтому зададим сразу lea si, prompt call print ;выведем приглашение на ввод строки бит
digits_loop: ;цикл ввода строки бит mov ah, 0 ;ждем символ int 16h cmp al,
0dh ;по Enter-у выходим из ввода je output cmp al, '0' ;проверим на '0' и '1' je num_ok cmp al, '1' jne digits_loop ;ждем только '0' и '1' num_ok: mov ah, 0eh ;выведем на экран int 10h
rcr al, 1 ;вдвинем младший разряд (0 или 1) в С rcl dl, 1 ;вдвинем С в наш байт! loop digits_loop ;по всем 8 битам
output: ;выведем результат ;hex значение для
красоты окружим 0 и h :) ;а символ окружим кавычками
;сначала выведем в виде hex-величины lea si, resultHex ;строка "hex: " call print
mov al, dl ;наш байт call PrintHex ;выведем hex
lea si, result ;строка "String: " call print
mov al, dl ;выведем байт int 10h mov al, '''' ;выведем кавычку int 10h
lea si, press ;выведем "Press any key" call print
mov ah, 0 ;ждем нажатия
на клавишу int 16h
mov ax, 4c00h ;выход int 21h
;вывод строки средствами BIOS ;функция 0eh - вывод телетайпом в текущей позиции, ;требует в bh номер страницы и в al - символ print proc mov ah, 0eh ;функция BIOS для вывода print_loop: lodsb ;очереднй символ test al, al ;строка заканчивается нулем jz print_ret int 10h ;сервис видео jmp print_loop print_ret: ret print endp
;вывод в виде hex
-величины PrintHex proc push ax ;сохраним байт (нам еще будет нужен младший полубайт) shr al, 4 ;старший полубайт call Pr
intDigit ;выведем hex-цифру pop ax ;восстановим and al,0fh ;младший полубайт PrintDigit: add al, 90h ;0-f -> '0'-'f' daa adc al, 040h daa mov ah, 0eh int 10h ;выведем ret PrintHex endp
cseg ends
dseg segment para public 'data' prompt db 'Enter binary string: ',0 resultHex db 0dh,0ah,'Hex: 0',0 result db 'h, Symbol: ''',0 press db 0dh,0ah,'Press any key for exit',0 dseg ends
end start
----- Удачи!
Ответ отправил: Лысков Игорь Витальевич, Модератор
Ответ отправлен: 02.04.2010, 10:50
Номер ответа: 260530 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 260530
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.