Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Чемпионы рейтинга экспертов в этой рассылке Номер выпуска: | 1335 | Дата выхода: | 12.05.2010, 11:00 | Администратор рассылки: | Лысков Игорь Витальевич, Модератор | Подписчиков / экспертов: | 279 / 59 | Вопросов / ответов: | 4 / 4 | IRC-канал по теме: | #assembler | Вопрос № 178235: Здравствуйте уважаемые эксперты! Нужно написать программу: Построение графика функции f(x)=cos(n*x+m*Pi), входные данные -- n и m, выходные -- график. Использовать TASM. Сделать в DOS. ... Вопрос № 178239: Здравствуйте уважаемые эксперты! У меня возникло затруднение - надо написать программу на TASM которая объединяет слова, начинающиеся на один и тот же символ и дописывает его (объединенное слово) в конец строки и вывести их на экран. слова вводить... Вопрос № 178248: Уважаемые эксперты, помогите пожалуйста написать программу: Составить программу сложения N (N<16) однобайтных чисел. Числа должны располагаться в памяти программ, начиная с адреса после кодов программы. Результат должен фиксироваться в ячейках... Вопрос № 178252: Здравствуйте,помогите пожалуйста с программой!У меня в файле число!Нужно вывести его цифры в обратном порядке!Есть программа по выводу исходных данных из этого файла!Число 127!Спасибо!... Вопрос № 178235: Здравствуйте уважаемые эксперты! Нужно написать программу: Построение графика функции f(x)=cos(n*x+m*Pi), входные данные -- n и m, выходные -- график. Использовать TASM. Сделать в DOS. Отправлен: 06.05.2010, 17:06 Вопрос задал: rmka, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, rmka. Вводим вещественные коэффициенты n и m, затем рисуем график Сейчас сделано так, что 25 точек на экране (переменная coef) соответствуют единице.
Код: ;Построение графика функции f(x)=cos(n*x+m*Pi), ;входные данные -- n и m, выходные -- график.
.model tiny, C ; модель памяти и порядок вызова параметров .386 ; нужно для команды fcos .code ; сегмент кода .startup ; точка входа
;введем N и M call GetNum, offset sN, offset NMax, offset N call GetNum, offset sM, offset MMax, offset M
;преходим в графику mov ax, 0013h ; vga 320x200x256 int 10h
mov ax, 0a000h mov es, ax ; es - сегмент видео
call line, 20, 100, 300, 100, 8 ;ось абсцисс call line, 160 , 20, 160, 180, 8 ;ось ординат call Graph, 20, 300, offset fun, 0bh ;сам график call PrFun, 3 ;напишем функцию
mov ah, 0 ;ждем нажатие на любую клавишу int 16h
;выход в DOS mov ax, 0003h ; назад в текстовый режим int 10h
mov ax, 4c00h ; bye-bye int 21h
;Вводим вещственное число ;параметры: ;pStr - адрес строки приглашения ;pMax - адрес строки для ввода по функции 0ah ;pNum - адрес, куда пишем вещественное число GetNum proc pStr:word, pMax:word, pNum:word local i:word ;переменная для работы с сопроцессором
mov dx, pStr ;приглашение mov ah, 9 int 21h
mov dx, pMax ;вводим строку mov si, dx mov ah, 0ah int 21h
lea si, [si+2] ;на адрес введенной строки xor cx, cx ;ch=0 - признак целой части, ch=1 - дробная часть xor di, di ;число (без учета точки) GN_loop: lodsb ;очередной символ cmp al, 0dh je GN_Form ;прошли по всей строке cmp al, '.' je GN_Point ;точка cmp al, '0' jb GN_loop ;допускаем только цифры cmp al, '9' ja GN_loop
cmp ch, 0 je GN_dig ;целая часть - на формирование числа inc cl ;дробная - сначала посчитаем число цифр дробной части GN_dig: push ax ;умножаем старшие разряды на 10 и добавляем новый mov ax, 10 mul di mov di, ax pop ax and ax, 0fh add di, ax jmp GN_loop GN_Point: ;точка cmp ch, 1 je GN_loop ;если повтор точки, то игнорируем (на всякий случай) mov ch, 1 ;помечаем jmp GN_loop GN_Form: ;учтем дробную часть mov i, di ;запишем число в переменную fild i ;загрузим в сопроцессор mov ch, 0 ;сформируем счетчик во всем регистре cx jcxz GN_Save ;если дробной части нет, то на сохранение mov i, 10 ;константа для деления GN_Div: fild i ;cx раз делим на 10 fdiv loop GN_Div GN_Save: mov di, pNum ;адрес, куда сохраняем вещес твенное число fstp dword ptr [di] ;сохраняем результат в виде float ret GetNum endp
;считает ax=y=f(x) в экранных координатах ;параметр: x - экранная координата по горизонтали fun proc x:word mov ax, x ;сделаем из x знаковое число sub ax, 160 ;x=160 - центр экрана считаем нулем mov x, ax ;сохраним в переменной для загрузки в сопроцессор fild x ;грузим в сопроцессор fdiv coef ;делим на коэффициент coef точек = 1 fmul n ;x * n fldpi ;пи fmul m ;пи * m faddp ;x * n + пи * m fcos ;cos(x * n + пи * m) fmul coef ;масштабируем: умножаем на коэффициент coef:1 fistp x ;преобразуем в целое mov ax, 100 ;100 - центр экрана по вертикали sub ax, x ;ax - экранная координата по вертикали ret fun endp
;рисует график, последовательно соединяя точки отрезками ;параметры: ;xmin - левая экранная координата графика ;xmax - правая экранная координата графика ;pFun - адрес фун кции, вычисляющей экранную координату по вертикали ;col - цвет линий Graph proc xmin:word, xmax:word, pFun:word, col:word Graph_ loop: ;цикл рисования отрезков mov ax, pFun ;адрес функции call ax, xmin ;считаем y первой точки mov cx, ax ;сохраним в cx
mov ax, xmin ;найдем x соседней справа точки inc ax mov si, ax ;сохраним в s╕ cmp ax, xmax ;проверим, дошли и до правого края ja Graph_ret
mov ax, pFun ;адрес функции call ax, si ;ax = y второй точки
;рисуем линию (xmin, cx)-(si,ax) цветом col call line, xmin, cx, si, ax, col mov xmin, si ;готовим xmin для следующего шага jmp Graph_loop Graph_ret: ret Graph endp
;рисуем линию (x1,y1)-(x2,y2) цветом color Line proc uses di bx, x1:word, y1:word, x2:word, y2:word, color:byte local i:word, \ ;для работы со сопроцессором delta_x:word, \ ;длина проекции на ось абсцисс delta_y:word, \ ;длина проекции на ось ординат incx:word, \ ;приращение по X incy:word ;приращение по Y
;определим длину проекции на ось абсцисс и шаг по оси X mov ax, x2 sub ax, x1 ;ax=x2-x1;
;определим шаг по X (+1 если вперед, -1 если назад, 0 если не меняется) mov incx, 0 ;пусть incx=0 test ax, ax ;ax=delta_x jz set_delta_x ;не меняется jg set_x_1 ;вперед? dec incx ;назад, значит incx=-1 neg ax ;найдем ax=abs(delta_x) jmp set_delta_x ;на сохранение set_x_1: inc incx ;вперед, значит incx=1; set_delta_x: mov delta_x, ax ;delta_x = abs(x2-x1)
;определим длину проекции на ось ординат и шаг по оси Y mov ax, y2 sub ax, y1 ;ax=y2-y1;
;определим шаг по Y (+1 если вперед, -1 если назад, 0 если не меняется) mov incy, 0 ;пусть incy=0 test ax, ax ;ax=delta_y jz set_delta_y ;не меняется jg set_y_1 ;вперед? dec incy ;назад, значит incy=-1 neg ax ;найдем ax==abs(delta_y) jmp set_delta_y ;на сохранение set_y_1: inc incy ;вперед, значит incy=1; set_delta_y: mov delta_y, ax ;delta_y=abs(y2-y1) ;определим большее из проекц ий как основное напрвление cmp ax, delta_x ;ax=delta_y jge from_y ;y будет основным cmp delta_x, 0 ;проверим, чтобы не было delta_x=0 (для точки), jz Line_ret ; иначе будет деление на 0 ;delta_x>delta_y && delta_x!=0 ;основное направление - по оси X fild delta_y fidiv delta_x ;st=k=(float)(delta_y/delta_x)
;for (int i=0;i<delta_x;i++) xor cx, cx ;cx=i jmp cmp_i_x ;на проверку i<delta_x x_loop: ;тело цикла mov i, cx ;запишем переменную цикла в память (для сопроцессора) fld st ;st=st(1)=k fimul i ;st=k*i fimul incy ;st=incy*k*i call floor ;округлим до целого в большую сторону fistp i ;сохраним в переменной mov ax, i ;относительный номер строки на экране add ax, y1 ;добавим до ординаты начальной точки mov dx, 320 ;получим индекс начала строки экрана в сегменте экрана imul dx ; для этого умножим на длину в байтах одной стоки mov bx, ax ;сохраним bx=y=(y1+floor( incy*k*i))*320 ;посчитаем X mov ax, incx ;X меняется ровно на шаг приращения, imul cx ; умноженному на индекс точки add ax, x1 ;добавим абциссу начальной точки ax=x=x1+incx*i
add ax, bx ;сложим с индексом начала строки mov di, ax ;будем адресовать через di
mov al, color ;цвет точки mov es:[di], al ;рисуем!
inc cx ;на следующую точку cmp_i_x: cmp cx, delta_x ;дошли до конца? jl x_loop jmp Line_ret ;на выход from_y: ;вдоль оси Y fild delta_x fidiv delta_y ;st=k=(float)(delta_x/delta_y)
;for (int i=0;i<delta_y;i++) xor cx, cx ;cx=i jmp cmp_i_y ;на проверку i<delta_y y_loop: ;тело цикла mov ax, incy ;Y меняется ровно на шаг приращения, imul cx ; умноженному на индекс точки add ax, y1 ;добавим абциссу начальной точки ax=y=y1+incy*i mov dx, 320 ;получим индекс начала строки экрана в сегменте экрана imul dx ; для этого умножим на длину в б айтах одной стоки mov bx, ax ;сохраним bx=y=(y1+incy*i)*320 ;посчитаем X mov i, cx ;запишем переменную цикла в память ( для сопроцессора) fld st ;st=st(1)=k fimul i ;st=k*i fimul incx ;st=incx*k*i call floor ;округлим до целого в большую сторону fistp i ;сохраним в переменной mov ax, i ;относительный номер строки на экране add ax, x1 ;ax=x=x1+floor(incx*k*i)
add ax, bx ;сложим с индексом начала строки mov di, ax ;будем адресовать через di
mov al, color ;цвет точки mov es:[di], al ;рисуем!
inc cx ;на следующую точку cmp_i_y: cmp cx, delta_y ;дошли до конца? jl y_loop Line_ret: fistp i ;удалим из сопроцессора k ret Line endp
;округление до целого в большую сторону ;округление по умолчанию, до ближайщего, не устраивает floor proc local CtrlWordOld:word, CtrlWordNew:word fstcw CtrlWordOld ;сохраним управляющее слово fclex ;сбросим исключения mov CtrlWordNew, 0763h ;установим необходимое значение управляющего слова fldcw CtrlWordNew ;загружаем управляющее слово fr ndint ;округляем st до целого fclex ;сбросим исключения fldcw CtrlWordOld ;восстановим старое управляющее слово ret floor endp
;выводим на экран f(x)=cos(n*x+m*Pi) ;параметр textcolor - цвет текста PrFun proc textcolor:word mov bx, textcolor ;цвет lea si, Pr1 ;первая часть текста call PrText lea si, NText ;N в виде строки call PrText lea si, Pr2 ;вторая часть текста call PrText lea si, MText ;M в виде строки call PrText lea si, Pr3 ;третья часть текста call PrText ret PrFun endp
;выводим строку по адресу [si], строка должна заканчиваться 0dh PrText proc lodsb cmp al, 0dh je PrRet mov ah, 0eh int 10h jmp PrText PrRet: ret PrText endp
.data n dd 0 ;исходные коэффициенты m dd 0 coef dd 25. ;коэффициент для масштабирования на экране sN db 'N= $' sM db 0dh,0ah,'M= $' Pr1 db 'f(x)=cos(',0dh< br>Pr2 db '*x+',0dh Pr3 db '*Pi)',0dh NMax db 6 db 0 NText db 7 dup (0) MMax db 6 db 0 MText db 7 dup (0) END
----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 08.05.2010, 04:00 Номер ответа: 261278 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Оценка ответа: 5 Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261278 на номер 1151 (Россия) | Еще номера » | Вопрос № 178239: Здравствуйте уважаемые эксперты! У меня возникло затруднение - надо написать программу на TASM которая объединяет слова, начинающиеся на один и тот же символ и дописывает его (объединенное слово) в конец строки и вывести их на экран. слова вводить с клавиатуры. вот пример: waba wordos absen ; вводим исходную строку waba wordos absen wabawordos ; то что должно получиться дополнительные сведения: работа на TASM - 92 для процессора 8086 под дос (командная строка в windows xp) предназначена для учебы. и пожалуйста напишите программу наиболее простым способом (понятным для студента ) и прокомментируйте строчки я в ассемблере не очень силен  P.S. а можно будет задавать вопросы по пришлённому ответу если в нем что то неясно будет ? Большое спасибо! Отправлен: 06.05.2010, 17:56 Вопрос задал: Timmy, Посетитель Всего ответов: 1 Страница вопроса » Отвечает amnick, 10-й класс : Здравствуйте, Timmy.
В приложении приведен мой вариант решения Вашей задачи. Схема такая: читаем строку с клавиатуры в буфер, разбиваем ее на слова. Слова могут быть разделены одним или несколькими символами, перечисленными в массиве delimiters, так что Вы легко можете изменить разделители. Для каждого слова сохраняется его длина и указатель на начало. Предполагается, что слов не более 20, при превышении выводится сообщение и программа прекращает работу. После заполнения массивов программа в цикле проверяет первые буквы слов на совпадение и дополняет входной буфер объединенными словами. В конце выводится результат.
Программа должна компилироваться в COM-файл.
Если есть вопросы, то обращайтесь в мини-форум, постараюсь помочь.
Успехов! Приложение: Ответ отправил: amnick, 10-й класс Ответ отправлен: 06.05.2010, 23:11 Номер ответа: 261244 Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261244 на номер 1151 (Россия) | Еще номера » | Вопрос № 178248: Уважаемые эксперты, помогите пожалуйста написать программу: Составить программу сложения N (N<16) однобайтных чисел. Числа должны располагаться в памяти программ, начиная с адреса после кодов программы. Результат должен фиксироваться в ячейках внешней памяти, начиная с адреса 0000H. Заранее благодарен. Отправлен: 06.05.2010, 23:01 Вопрос задал: diavolic89, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, diavolic89. Ваша программа:
Код: ;Программа сложения N (N<16) однобайтных чисел. ;Числа располагаются в памяти программ, начиная с адреса после кодов программы. ;Результат фиксируется в ячейках внешней памяти, начиная с адреса 0000H. sumaddr equ 0 ;адрес внешней памяти, куда запишем результат sumlow equ 8 ;переменные во внутренней памяти для суммы, младший байт sumhigh equ 9 ;старший байт stack eqy 60h ;вершина стека
mov sp, #stack ;стек
mov dptr, #array ;адрес массива в программной памяти mov r2, #0 ;индекс в массиве mov r3, #N ;количество элементов массива mov sumlow, #0 ;пусть сумма пока равна 0 mov sumhigh, #0 loop: ;цикл по складыванию элементов массива mov a, r2 ;индекс очередного элемента inc r2 ;для следующего movc a, @a+dptr ;читаем в аккум из программной памяти байт по адресу [a]+[dptr] add a, sumlow ;складываем с младшим mov sumlow, a ;сохраняем младший байт mov a, #0 ;надо учесть перенос! addc a, sumhigh ;для этого складываем старший байт с 0 и с переносом (FC) mov sumhigh, a ;сохраняем старший байт djnz r3, loop ;r3=r3-1; циклим, пока r3!=0
mov dptr, #sumaddr ;пишем найденную сумму во внешнюю память mov a, sumlow ;сначала младший байт movx @dptr, a ;пишем a->[dptr] inc dptr mov a, sumhigh ;следом старший байт суммы movx @dptr, a ;пишем a->[dptr]
jmp $ ;задача решена, организовываем бесконечный цикл: ; крутимся на одном месте
array: ;данные db 3,6,4,8,2,0,3,7,1,6,5,3,8,2,23h,10h N equ $-array ;длина массива
end
Обратите внимание, что сумма в двух байтах ----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 07.05.2010, 10:59 Номер ответа: 261264 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Оценка ответа: 5 Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261264 на номер 1151 (Россия) | Еще номера » | Вопрос № 178252: Здравствуйте,помогите пожалуйста с программой!У меня в файле число!Нужно вывести его цифры в обратном порядке!Есть программа по выводу исходных данных из этого файла!Число 127!Спасибо! Отправлен: 06.05.2010, 23:31 Вопрос задал: Калинина Е.А., Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, Калинина Е.А.. Вы написали программу в формате Debug-а. Я решил написать в формате TASM-а. Так же нагляднее :) Кроме того, добавил обработку ошибок... Если что непонятно, спрашивайте.
Код: .model tiny .code .startup
jmp continue
FName db 'c:\file1.txt',0 Num db 'dan$' ErrNotFound db 'File not found$' ErrRead db 'Read error$'
continue: mov ax, 3d00h mov dx, offset FName int 21h jc ErrorNotFound ;файл не найден mov bx, ax mov ah, 3fh mov cx, 3 mov dx, offset Num int 21h jc ErrorRead ;ошибка чтения mov ah, 3eh int 21h
mov al, Num ;меняем местами 1 и 3 байты :) xchg al, Num+2 mov Num, al mov ah,9 ;dx указывает на число int 21h ret
ErrorRead: mov dx, offset ErrRead jmp PrintError ErrorNotFound: mov dx, offset ErrNotFound PrintError: mov ah, 9 int 21h ret
end
----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 07.05.2010, 12:03 Номер ответа: 261265 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Оценка ответа: 5 Комментарий к оценке: Спасибо огромное!!! Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 261265 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий