Другое > 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.
Навигация
Главная страница сообщений
Следующая страница

Перейти к полной версии