| Другое > Hard'n'Soft |
| Помогите с ассемблером (TASM) |
| (1/2) > >> |
| Henty:
В универе лаботарорку задали, нарисовать график. При подсчёте использовать со-процессор для вычислений. Программу я написал, но есть одна проблема. У меня вылетает с ошибкой в файле ntvdm.exe, то есть я убиваю ДОС :D Ниже задание, и мой код. ********************************************************************* ********************************************************************* Нарисовать параметрический график. / x(t) = Mx*sin(At)+Ox \ y(t) = My*cos(Bt)+Oy параметр t меняется от 0 до 2пи шагом 0,001 коефициенты масштаба Mx,My,Ox,Oy выбираются в соответствии с видеорежимом. Натуральные коефициенты A и B вводятся с клавиатуры. ********************************************************************* ХОД РАБОТЫ: 0. Подготовка: выбрать графический режим (прерывание 10h, функция 0) и вычислить целые коефиценты Mx, My, Ox и Oy как половина размеров экрана (Mx = Ox = ШИРИНА / 2, My = Oy = ВЫСОТА / 2) 1. в первых двух строчках разрешить использование i80386 процессора .386 .MODEL use16 small 2. Создать двухбайтовые переменные Mx, My, Ox, Oy с вычисленными значениями 3. Запросить с клавиатуры и переделать в целые числа A и B 4. Переключить видеокарту в графический видеорежим (прерывание 10h, функция 0) 5. Подготовить счётчик циклов Step = 0 6. записать в "польской" записи формулу и вычислить с помощью сопроцессора значение X: X = Mx * sin(A * Step / 1000) + Ox 7. Iзаписать в "польской" записи формулу и вычислить с помощью сопроцессора значение Y: Y = My * cos(B * Step / 1000) + Oy 8. Нарисовать на экране точку с координатами X, Y (прерывание 10h, функция 0Ch) 9. Увеличить счётчик цикла Step на 1, если Step меньше 6284 (2Пи * 1000), то перейти на пункт 6. 10. Пауза до нажатия клавиши 11. Переключить видеокарту в режим текста (прерывание 10h, функция 0) ********************************************************************* Вот такое вот задание. вот мой горе-код. --- Код: ---.386 .MODEL use16 small .STACK 200h .DATA Mx dw ? My dw ? Ox dw ? Oy dw ? A dw ? B dw ? X dw ? Y dw ? Astr DB 6, ?, 5 dup (?) Bstr DB 6, ?, 5 dup (?) Step dw ? .CODE ProgramStart: mov ax, @DATA mov DS, ax ;--------------------------------] ;2. Создать двухбайтовые переменные Mx, My, Ox, Oy с вычисленными значениями ;--------------------------------] mov Mx, 160 mov My, 120 mov Ox, 160 mov Oy, 120 ;--------------------------------------------------- mov ah, 0fh ; узнать видеорежим int 10h mov ah, 00h ; установить видеорежим int 10h ;--------------------------------------------------- mov ah, 0ah ; запрос строки Astr mov dx, offset Astr int 21h ;--------------------------------------------------- mov ah, 0fh ; узнать видеорежим int 10h mov ah, 00h ; установить видеорежим int 10h ;--------------------------------------------------- mov ah, 0ah ; запрос строки Bstr mov dx, offset Bstr int 21h ;--------------------------------------------------- mov ah, 0fh ; узнать видеорежим int 10h mov ah, 00h ; установить видеорежим int 10h ;--------------------------------------------------- ; переводим число А из строки Astr ;--------------------------------------------------- mov CL, Astr[1] ;CL = кол-во символов mov AX, 0 ;AX = 0 mov SI, offset Astr[2] ;SI = адрес первого введённого символа Frml1: mov Bx, 10 ; AX:=AX*10 mul Bx mov BL, [SI] ;[SI]-'0' mov BH, 0 sub BX, '0' add AX, BX ;Ax:=Ax*10+([SI]-'0') inc SI ;SI:=SI+1 dec CL ;CL:=CL-1 cmp CL,0 ; if CL <>0 then goto Frml jne Frml1 mov A, AX ;--------------------------------------------------- ; переводим число B из строки Bstr ;--------------------------------------------------- mov CL, Bstr[1] ;CL = кол-во символов mov AX, 0 ; AX = 0 mov SI, offset Bstr[2] ; SI = адрес первого введённого символа Frml2: mov Bx, 10 ; AX:=AX*10 mul Bx mov BL, [SI] ;[SI]-'0' mov BH, 0 sub BX, '0' add AX, BX ;Ax:=Ax*10+([SI]-'0') inc SI ;SI:=SI+1 dec CL ;CL:=CL-1 cmp CL,0 ; if CL <>0 then goto Frml jne Frml2 mov B, AX ;--------------------------------------------------- mov ah, 0Fh Int 10h ; узнать видеорежим mov ah, 13H Int 10h ; установить видеорежим в режим 640*480 ;--------------------------------------------------- ;/////////////////////////////////////////////////// ;--------------------------------------------------- ; Подсчёты и цикл ;--------------------------------------------------- mov step, 0 Draw: fild A fild Step fmul mov B, 1000 fild B fdiv fsin fild Mx fmul fild Ox fadd fist X fild B fild Step fmul mov A, 1000 fild A fdiv fcos fild My fmul fild Oy fadd fist Y ; ставим точку mov AH, 0ch mov AL, 7 mov BH, 0 mov CX, X mov DX, Y int 10h inc Step cmp step, 6284 jl Draw ;-------------------------------------------------- xor ah, ah ;пауза до нажатия клавиши int 16h mov ah, 4ch int 21h ;-------------------------------------------------- mov ah, 0Fh Int 10h ; узнать видеорежим mov ah, 00h Int 10h ; установить видеорежим текста ;--------------------------------------------------- END ProgramStart --- Конец кода --- *************************************************************** Кто может, помогите найти ошибку. прога вылетает на месте, где я ставлю первый пиксель. Может я с прерыванием что-то напутал? или не так перешёл в видео режим? |
| Йобан Матич:
--- Цитата: Henty ---или не так перешёл в видео режим? --- Конец цитаты --- --- Цитата ---mov ax, 0013h int 10h --- Конец цитаты --- попробуй так ps: зачем видеорежим устанавливать много раз подряд ? |
| Zephyr:
--- Код: ---; Процедура putpixel12h. ; Выводит на экран точку с заданным цветом в режиме 12h (640x480x16). ; Вход: DX: строка ; CX: столбец ; BP: цвет ; ES: 0A000h putpixel12h proc near pusha ; Вычислить номер байта в видеопамяти. xor bx,bx mov ax,dx ; AX= строка lea eax,[eax+eax*4] ; AX = AX x 5 shl ax,4 ; AX = AX x 16 ; AX = строка х байт_в_строке ; (строка x 80) push cx shr cx,3 ; CX = номер байта в строке add ax,cx ; AX = номер байта в видеопамяти mov di,ax ; Сохранить его в DI ; Вычислить номер бита в байте pop cx and cx,07h ; Остаток от деления на 8 - номер ; бита в байте, считать справо налево. mov bx,0080h shr bx,cl ; В BL теперь нужный бит установлен в 1. ; Программирование портов. mov dx,03CEh ; Индексный порт ; графического контроллера mov ax, 0F01h ; Регистр 01h: разрешен ; установки/сброса. out dx,ax ; Разрешить установку/сброс для ; всех плоскостей (эту часть лучше ; сделать однажды в программе, например сразу после установки ; видеорежима, и не повторять каждый раз при вызове процедуры). mov ax,bp shl ax,8 ; Регистр 00h: регистр ; установки/сброса. out dx,ax ; AH = цвет. mov al,08 ; Порт 08h: битовая маска mov ah,bl ; Записать в битовую маску нули ; всюду кроме out dx,ax ; бита, соответствующего выводимому пикселу. mov ah, byte ptr es:[di] ; Заполнить ; регистры-защелки mov byte ptr es:[di],ah ; Вывод на экран: ; выводится единственный бит ; в соответствии с содержимым регистра битовой маски, остальные ; биты берутся из защелки, то есть не изменяются. Цвет выводимого ; бита полностью определяется значением регистра установки/сброса. popa ret putpixel12h endp --- Конец кода --- |
| Henty:
Йобан Матич,Zephyr, спасибо за помощь. --- Цитата ---зачем видеорежим устанавливать много раз подряд ? --- Конец цитаты --- 1-й раз - очистка экрана от "остатков" командной строки 2-й раз после введения первого коефициента 3-й раз после введения второго коефициента Zephyr, к сожалению это будет явно запально что скатал) Да и кое-что объяснить не смогу. :-\ Нашёл несколько ошибок. 1) В конце расчётов X и Y я не округлял результат frndint и не удалял со стека старое значения, когда забирал данные переменной. (вместо fist написал fistp) 2) Прерывание на выход стоит раньше объявления режима текста. Но сцукО вылетает так же =\ Йобан Матич, поменял, та же херь.. |
| Henty:
Понял в чём косяк! --- Цитата --- mov ah, 0 -сюда писал не то что надо) mov al, 12h - я не дописывал эту важную строчку с номером видеорежима. Int 10h ; установить видеорежим в режим 640*480 --- Конец цитаты --- |
| ALEX_230_VOLT:
сори за оффтоп, но нифига себе у вас задания 0_0 мы пока тока Паскаль мусолим и даже динамических переменных не заходили |
| Henty:
Прогу написал, тему можно закрывать :) Путём проб и ошибок добился своего. Алекс, ну как учат)) помимо асма у нас ещё и Delphi)) ^_^ |
| HardWareMan:
Ну мы учили х86 асм, пас, С и даже на Дельфи чото задавали (например, было задание с драг'н'дроп). Жаль поздно тему заметил... :( |
| Henty:
Паскаль я дома сам учил. Теперь при работе в Делфи на Object Pascal намного легче, чем остальным) :) но это уже ОффтопЪ |
| HardWareMan:
--- Цитата: Henty от 16 Декабрь 2008, 16:31:30 ---Паскаль я дома сам учил. Теперь при работе в Делфи на Object Pascal намного легче, чем остальным) :) но это уже ОффтопЪ --- Конец цитаты --- Ага, переведенный кем-то turbo.hlp очень рулил... ;) |
| BlueHairLady:
Попыталась самостоятельно освоить Delphi 7, но как-то подзастряла. Возможно, стоит поискать какие-нибудь курсы, но мне сейчас просто не до этого. Ну а хорошую русскоязычную справку по Delphi (и по C++) можно найта на http://www.delcb.com/InHelp.htm . |
| Henty:
--- Цитата ---Ага, переведенный кем-то turbo.hlp очень рулил... --- Конец цитаты --- o_0 Телепат))) BlueHairLady, пасиба, в самый раз. Тока платна :( |
| feki38:
Я Delphi 7 уже освоил. Уже перешел (частично) на Delphi 2009. Последний мне нужен для портирования прог написанных в Delphi 7 под висту :). ИМХО - Дельфи 7 удобнее 2009. |
| AnXIouS:
У нас тоже таких сложных задач не было. Зато в этом году курсач порадовал )) "Разработать транслятор с языка паскаль на ассемблер". |
| Zephyr:
AnXIouS, Если это было сложно, а это впринципе не так, то транслятор это вообще потолок!!! Точно ли транслятор? Может быть конвертер исходных текстов? Сам транслятор должен перегонять команды по 1, прямо во время сборки программы - проверять команду - и если есть ошибка, прекращать работу. В настоящие время процесс трансляции используется только в среде Visual Basic, насколько мне известно. |
| AnXIouS:
Zephyr, я сказал сложно, по сравнению с тем что нам задавали. В общем ничего сложного не спорю. А курсовик да, тупой конвертер исходников, но зато как назывался ... |
| Zephyr:
Ну конвертер написать тоже попыхтеть нужно ;) Я подумал что у вас преподователи реально потребовали транслятор :) Я конечно же не знаю их квалификации, но попросту засомневался в том что они сами способны написать транслятор с языков высокого уровня. Просто мой экзаменатор информатики тупо копировал вопросы с книги. В итоге пришлось выручать более чем 8 человек при сдаче... Решать за них. Хотя все готовились неплохо. За это он мне кстати влепил самый маленький проходной бал при верной работе. Со словами: "скажи спасибо что вообще не выгнал". :( А недавно увиденные мною вопросы для поступления в 1 из Минских ВУЗов на факультет информатики просто повергли меня в шок. Бездумно переписаные вопросы из разных частей книги. Ни 1 даже подготовленный программист не сдаст ЭТО на отлично. Грустно короче... |
| HardWareMan:
--- Цитата: AnXIouS от 17 Январь 2009, 12:58:06 ---У нас тоже таких сложных задач не было. Зато в этом году курсач порадовал )) "Разработать транслятор с языка паскаль на ассемблер". --- Конец цитаты --- Тюююю... Берете исходник компилятора Паскаля и откручиваете стадию компиляции готового асм.текста в бинарник. Получаете автоматом текст на Ассемблере. %) |
| feki38:
Транслятор с паскаля на асм - по сути (HardWareMan прав) компилятор. Просто он не переводит асм-текст в "чистый" машинный код. То есть согласен с HardWareMan'ом. |
| atamax:
Привет всем Помогите пожалуйста! день и ночь думаю о ней, так как новичок не знаю с какрй стороны подойти к ней надо написать на языке TurboAssembler программу, которая выводит на экран монитора график функции y=ax^2-bx+c на интервале аргументов х=[0-500]. a. Коэффициенты a, b, c подобрать самостоятельно с учетом наилучшей наглядности отображения графика. b. Цвет осей – белый, c. Отметить на графике точку пересечения функций и вывести значения ее координат. d. График должен выводиться как на монитор (в графическом режиме), так и в файл (в текстовом режиме, без цветовых градаций). e. цвет графика – красный при у>0, - синий при y<0. |
| Навигация |
| Главная страница сообщений |
| Следующая страница |