Другое > Hard'n'Soft
Помогите с ассемблером (TASM)
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.
Навигация
Перейти к полной версии