include Draw.inc
.model small
.stack 100h
.386
.data
pkey db "press any key...$"
input1 db "Input coordinate X0(60<X0<640): $"
input2 db "Input number of obstacles (from 1 to 10): $"
input3 db "Input coordinates of obstacles (x1 y1 x2 y2): $"
winput db "wrong input...$"
coordX0 dw ? ;координата Х0
X0 dw 0
count dw ? ;кол-во препятствий
linesize dw ? ;размер пунктирной ломаной
array dw 150 dup (0) ;массив отрезков(формат x1,y1,x2,y2)
x dw 0 ;массив абсцисс кривой
y dw 0 ;массив ординат кривой
endl db 0dh,0ah,'$' ;перевод на другую строку
x1 dw 0 ;координаты концов линии
x2 dw 0
y1 dw 0
y2 dw 0
xk dw 0
yk dw 0
min dw 0
max dw 0
index dw 0
value dw 0
alpha dd 0.0 ;изменяющаяся переменная
delta dd 0.001 ;величина изменения
delta2 dd 0.01 ;это для линий, вполне хватает
xdiv2 dw 0 ;центр выводимой фигуры (обычно)
ydiv2 dw 0
tmp dd 0.0 ;temp
tmp2 dd 0.0
x3 dd 3.0
x10 dd 10.0
divK dw 0
xr dw 0 ;координаты выводимой точки
yr dw 0
rx dw 0 ;масштабные коэффициенты (параметры)
ry dw 0
xarray dw 400 dup(0)
yarray dw 400 dup(0)
PX dw 0 ;x координата точки
PY dw 0 ;y координата точки
S1 dw 0
S2 dw 0
DeltaX dw 0
DeltaY dw 0
obmen dw 0
e dw 0
ends
.code
start:
; set segment registers:
mov ax, @data
mov ds, ax
mov es, ax
endline MACRO
mov ah,09h
lea dx,endl
int 21h
ENDM
;+---------------------------------------------+
;| ввод начальных параметров |
;+---------------------------------------------+
JUMPS
;ввод координаты Хо
lea dx, input1
mov ah, 9
int 21h
endline
call ReadInteger
mov coordX0,ax
mov bx,coordX0
;проверка значения координаты Хо(60<Хо<640)
cmp coordX0,60
jbe wrong_input
cmp coordX0,640
jae wrong_input
;ввод количества препятствий
endline
lea dx, input2
mov ah, 9
int 21h
endline
call ReadInteger
mov count,ax
mov bx,count
;проверка количества препятсвий (отрезков)
cmp count,0
jbe wrong_input
cmp count,11
jae wrong_input
;ввод координат отрезков
endline
lea dx, input3
mov ah, 9
int 21h
endline
call ReadArray
endline
;переход в графический режим
mov AX,0012h
int 10h ;видеорежим 640x480
MOV AH,0CH
DrawAxis
call DrawLines
mov ah,1h ;ожидание нажатия клавиши
int 21h
mov ax, 4c00h ;exit to operating system.
int 21h
;====================================================================
;+---------------------------------------------+
;| выход и обработка ошибок |
;+---------------------------------------------+
;при ошибке выводим сообщение и завершаем работу
wrong_input:
lea dx, winput
mov ah, 9
int 21h ; output string at ds:dx
jmp exit
push ax ; сохранение регистров
push bx
push cx
push dx
push si
push di
;завершение работы
exit:
endline
lea dx, pkey
mov ah, 9
int 21h ;output string at ds:dx
mov ah, 1 ;wait for any key....
int 21h
int 21h
mov ax, 4c00h ;exit to operating system.
int 21h
DrawLines proc
push ax ;сохранение регистров
push bx
push cx
push dx
push di
mov cx,count ;помещаем кол-во отрезков для цикла
mov di, 0 ;индексы для извлечения из array
Z:
push cx
mov ax, array[di]
add di,2 ;увеличиваем счетчики
mov bx, array[di]
add di,2 ;увеличиваем счетчики
mov cx, array[di]
add di,2 ;увеличиваем счетчики
mov dx, array[di]
line ax,bx,cx,dx
pop cx
LOOP Z ; цикл по количеству отрезков
pop si
pop di
pop dx
pop bx
pop cx
ret
DrawLines endp
; ВВОД ДЕСЯТИЧНОГО ЧИСЛА В AX
ReadInteger proc
push cx ; сохранение регистров
push bx
push dx
xor cx, cx
mov bx, 10
call ReadChar ; ввод первого символа
;cmp al,'-' ; если минус - ошибка
;je wrong_input
jmp not_minus
read:
call ReadChar ; ввод очередного символа
not_minus:
cmp al, 13 ; Enter ?
je done ; да - > завершение
sub al, '0' ; нет -> перевод цифры char -> int
xor ah, ah
xor dx, dx
xchg cx, ax
mul bx
add ax, cx
xchg ax, cx
jmp read
done:
xchg ax, cx
pop dx
pop bx
pop cx
ret
ReadInteger endp
ReadChar proc
mov ah,1
int 21h
ret
ReadChar endp
;+--------------------------------------------------+
;| ВВОД МАССИВА ЧИСЕЛ (РАЗДЕЛЕННЫХ ПРОБЕЛОМ) - array|
;+--------------------------------------------------+
ReadArray proc
push cx ; сохранение регистров
push bx
push dx
push di
push si
mov di,-2
mov si,-1
start_ra:
inc si
add di,2 ;увеличение индекса очередного элемента
mov ax, 4h
mov bx, count
mul bx ;умножаем count на 4
cmp si, ax ;проверка на превышение размера массива
je end_ra
xor cx, cx
mov bx, 10
call ReadChar ; ввод первого символа
;cmp al,'-' ; если минус - ошибка ввода
; je wrong_input
jmp not_minus_ra
read_ra:
call ReadChar ; ввод очередного символа
not_minus_ra:
cmp al, ' ' ; Space ?
je done_ra ; да - > завершение ввода числа
cmp al, 13 ; Enter ?
je end_ra ; да - > завершение ввода
sub al, '0' ; нет -> перевод цифры char -> int
xor ah, ah
xor dx, dx
xchg cx, ax
mul bx
add ax, cx
xchg ax, cx
jmp read_ra
done_ra:
xchg array[di], cx
jmp start_ra
end_ra:
xchg array[di], cx
pop si
pop di
pop dx
pop bx
pop cx
ret
ReadArray endp
ends
end start ; set entry point and stop the assembler.
[ASM] Ошибка передачи параметров макросу
Проблема с рисованием в asm, использую компилятор TASM.
Имеется процедура DrawLines для рисования отрезков(в ней вызывается макрос собственно рисования линий), используя массив, с ранее введеными координатами этих отрезков, в этой процедуре вся проблема, при передаче параметров наверное.
компилятор ошибок не выдает. Подскажите что неверно в процедуре DrawLines?
Файл Beg.asm основной
Код:
Подключаемый файл Draw.inc
Код:
;макрос вывода пиксела на экран с коорд. x,y и цветом color
PutPixel macro x,y,color
pusha
mov ah,0ch
mov al,color
mov bh,0h
mov cx,x
mov dx,y
int 10h
popa
endm
Line macro x,y,xk,yk ; макрос рисования линии
local l1,l2,l3
pusha
mov x1,x
mov x2,xk
mov y1,y
mov y2,yk
mov ax,x1
mov bx,x2
cmp ax,bx
jg l2
mov xdiv2,x
mov ydiv2,y
mov ax,xk
sub ax,x
mov bx,y
sub bx,yk
jmp l3
l2:
mov xdiv2,xk
mov ydiv2,yk
mov ax,x
sub ax,xk
mov bx,yk
sub bx,y
l3:
mov rx,ax
mov ry,bx
finit ;инициализация сопроцессора
fild word ptr ry
fild word ptr rx
fdiv
fstp tmp
mov ax,rx
mov bx,100
mul bx
mov cx,ax
finit ;инициализация сопроцессора
fldz
fstp alpha
l1:
fld alpha ;st(0)=alpha
frndint ;st(0)=round(gx*alpha)
fild word ptr xdiv2 ;st(0)=xdiv2 st(1)=round(gx*alpha)
fadd ;st(0)=xdiv2+round(gx*alpha) - координата X найдена!!!
fistp word ptr xr ;заносим X в переменную для вывода на экран
fld alpha ;st(0)=alpha
fld tmp
fmul ;st(0)=gy*sin(alpha)
frndint ;st(0)=round(gy*sin(alpha))
fstp tmp2 ;tmp=round(gy*sin(alpha))
fild word ptr ydiv2 ;st(0)=ydiv2
fsub tmp2 ;st(0)=ydiv2-round(gy*sin(alpha)) - координата Y найдена!!!
fistp word ptr yr ;заносим Y в переменную для вывода на экран
PutPixel xr,yr,5 ;выводим точку зеленым цветом
fld delta2 ;вычисляем новое значение alpha
fld alpha
fadd
fstp alpha
loop l1 ;цикл по cx
endm
DrawAxis macro
mov cx,450
axis:
mov px,cx
mov py,450
add px,10
PutPixel px,py,4
mov py,cx
mov px,10
PutPixel px,py,4
loop axis
endm
PutPixel macro x,y,color
pusha
mov ah,0ch
mov al,color
mov bh,0h
mov cx,x
mov dx,y
int 10h
popa
endm
Line macro x,y,xk,yk ; макрос рисования линии
local l1,l2,l3
pusha
mov x1,x
mov x2,xk
mov y1,y
mov y2,yk
mov ax,x1
mov bx,x2
cmp ax,bx
jg l2
mov xdiv2,x
mov ydiv2,y
mov ax,xk
sub ax,x
mov bx,y
sub bx,yk
jmp l3
l2:
mov xdiv2,xk
mov ydiv2,yk
mov ax,x
sub ax,xk
mov bx,yk
sub bx,y
l3:
mov rx,ax
mov ry,bx
finit ;инициализация сопроцессора
fild word ptr ry
fild word ptr rx
fdiv
fstp tmp
mov ax,rx
mov bx,100
mul bx
mov cx,ax
finit ;инициализация сопроцессора
fldz
fstp alpha
l1:
fld alpha ;st(0)=alpha
frndint ;st(0)=round(gx*alpha)
fild word ptr xdiv2 ;st(0)=xdiv2 st(1)=round(gx*alpha)
fadd ;st(0)=xdiv2+round(gx*alpha) - координата X найдена!!!
fistp word ptr xr ;заносим X в переменную для вывода на экран
fld alpha ;st(0)=alpha
fld tmp
fmul ;st(0)=gy*sin(alpha)
frndint ;st(0)=round(gy*sin(alpha))
fstp tmp2 ;tmp=round(gy*sin(alpha))
fild word ptr ydiv2 ;st(0)=ydiv2
fsub tmp2 ;st(0)=ydiv2-round(gy*sin(alpha)) - координата Y найдена!!!
fistp word ptr yr ;заносим Y в переменную для вывода на экран
PutPixel xr,yr,5 ;выводим точку зеленым цветом
fld delta2 ;вычисляем новое значение alpha
fld alpha
fadd
fstp alpha
loop l1 ;цикл по cx
endm
DrawAxis macro
mov cx,450
axis:
mov px,cx
mov py,450
add px,10
PutPixel px,py,4
mov py,cx
mov px,10
PutPixel px,py,4
loop axis
endm
P.S.Юров штоле?;)
Код:
mov di, 0
mov ax, array[di] ; array массив с координатами линии
add di,2
mov bx, array[di]
add di,2
mov cx, array[di]
add di,2
mov dx, array[di]
line ax,bx,cx,dx
mov ax, array[di] ; array массив с координатами линии
add di,2
mov bx, array[di]
add di,2
mov cx, array[di]
add di,2
mov dx, array[di]
line ax,bx,cx,dx
ТО что-то не рисуется ничего)) В массив array складываются номральные числа, переведенные из ASCII кода.
Ясен перец оно не будет рисоваться!У тебя ж регистры пересекаются те,которые ты вписал в аргументы,и те,которые в самом макросе.Так что меняй структуру