Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

Boriss
Статус: Академик
Рейтинг: 2420
∙ повысить рейтинг »
_Ayl_
Статус: Профессионал
Рейтинг: 1843
∙ повысить рейтинг »
vladisslav
Статус: 6-й класс
Рейтинг: 1227
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И ПО / Программирование / Assembler (Ассемблер)

Номер выпуска:1349
Дата выхода:01.06.2010, 00:30
Администратор рассылки:Лысков Игорь Витальевич, Модератор
Подписчиков / экспертов:261 / 63
Вопросов / ответов:5 / 5
IRC-канал по теме:#assembler

Вопрос № 178507: Доброго времени суток, уважаемые эксперты! Прошу помочь с такой задачей: необходима программа морфинга из звезды в круг. (число граней, цвет - в задаче не обозначены) . DOS, TASM.Заранее спасибо. ...


Вопрос № 178653: помогите пожалуйста,эксперты!есть код программы,но проблема в том что значения записываются во внутреннюю память,а нужно чтобы записывались во внешнюю память! name var3   DSEG    AT  30h                CSEG    AT   0h   jmp mai...
Вопрос № 178661: Здравствуйте уважаемые эксперты! Требуется решить такую задачку: Составить программу, выводящую на экран и в задаваемый с клавиатуры файл десятичное представление двойного факториала. Должна быть работоспособна для вычисления 1000!!. Число тож...
Вопрос № 178664: Вычислить значение выражения Ax^2+Bx+C на интервале [Xmin; Xmax] с шагом 1. Вывести аргумент и значение функции в виде таблицы. Организовать вывод ФИО, уникального номера, текущего системного времени и даты. Xmin=3 Xmax=7 A=1 B=3 C=2 Процес...
Вопрос № 178666: Здравствуйте уважаемые эксперты! Помогите пожалуйста решить задачу, имеется строка - предложение из нескольких слов. Написать процедуру, осуществляющую запись тех же строк словами, переписанными с конца наперед. Дополнительных массивов не исп...

Вопрос № 178507:

Доброго времени суток, уважаемые эксперты! Прошу помочь с такой задачей: необходима программа морфинга из звезды в круг. (число граней, цвет - в задаче не обозначены) . DOS, TASM.Заранее спасибо.

Отправлен: 19.05.2010, 21:10
Вопрос задал: Виктор Никанорович, Посетитель
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, Виктор Никанорович.
Наконец-то появилось время написать программу...
Достаточно неочевидную, между прочим, т.к. необходимо знание математики.
Код:

.model tiny, C
.386

R equ 80 ;радиус окружности
N equ 20 ;число итераций

POINT struc ;структура для хранения информации о меняющейся точке
X0 dd ? ;расстояние от центра точки по Х исходной звезды
FY dw ? ;индекс функции, вычисляющей Y исходной звезды
Xd dd ? ;приращение по Х для следующей итерации
Xi dd ? ;Х позиции точки при очередной итерации
POINT ends

.code
.startup
call FormPoints ;формируем информацию о точках правой половины звезды

mov ax, 0013h ; vga 320x200x256
int 10h

mov ax, 0a000h
mov es, ax ; es - сегмент видео

call PrintFigure,0bh ;рисуем нулевую итерацию - исходную фигуру - звезду
mov ah,0
int 16h ;для начала морфинга ждем нажатия на клавишу
mov cx, N ;число итераций
FigureOff:
call PrintFigure,0 ;вытираем старую итерацию
call PrintFigure,0bh ;рисуем новую итерацию

call DELAY ;пауза

loop FigureOff ;рисуем N раз

WaitEscape:
mov ah, 0
int 16h ;выходим по Esc
cmp ah, 1
jne WaitEscape

;выход в DOS
mov ax, 0003h ; назад в текстовый режим
int 10h

mov ax, 4c00h ; bye-bye
int 21h

;Формируем массив с инфой обо всех точках
;для квадрата достаточно иметь инфу о половине стороны
FormPoints proc
local num:word, radius:word, x2:word

lea di, pPoints ;будем хранить инфу сразу за программой
mov radius, R ;радиус

;посчитаем некоторые необходимые константы
;tg(54), tg(36), sin(36), cos(18), sin(18), tg(18)

fldpi ;Пи
fimul c 54 ;Пи*54
fidiv c180 ;Пи*54/180 - угол в радианах
fsincos ;st = cos(54), st(1) = sin(54)
fdiv ;st = st(1)/st = tg(18)
fstp tg54 ;сохраним tg(54)

fldpi ;Пи
fimul c36 ;Пи*36
fidiv c180 ;Пи*36/180 - угол в радианах
fsincos ;st = cos(36), st(1) = sin(36)
fld st(1) ;st = sin(36)
fstp sin36 ;сохраним sin(36)
fdivp ;st = st(1)/st = tg(36)
fstp tg36 ;сохраним tg(36)

fldpi ;Пи
fimul c18 ;Пи*18
fidiv c180 ;Пи*18/180 - угол в радианах
fld st ;st = st(1)
fsincos ;st = cos(18), st(1) = sin(18)
fstp cos18 ;сохраним cos(18)
fstp sin18 ;сохраним sin(18)
fptan ;st(1) = tg(st) = tg(18), st = 1
fxch ;st(1) = 1 st = tg(18)
fstp tg18 ;сохраним tg(18)
fsub sin18 ;1-sin(18)
fimul radius ;(1-sin(18))*R
;сохраним Y точки конца первого участка, понадобится дальше
fst fy1 ;y1 = (1-sin(18))*R
fmul tg18 ;y1 * tg(18) - Х координата первого поворота
;сох раним Х точки конца первого участка, понадобится дальше
fst fx1 ;x1 = (1-sin(18))*R*tg(18)
fistp num ;num - число точек по Х до первого поворота

;первый участок - правый отрезок верхнего луча
mov cx, num ;число точек первого участка
mov num, 0 ;начинаем с х=0
X1Loop:
fild num ;x
fst [POINT ptr di].X0 ;сохраним, как (float)x0
fstp [POINT ptr di].Xi ;и как начальный x
mov [POINT ptr di].FY, offset CalcY1 ;функция вычисления Y
;расчитаем приращение по Х для морфинга по лучам из (0,0)
call CalcDelta, N, radius
add di, size POINT ;на следующую точку
inc num ;x=x+1
loop X1Loop ;по всем точкам первого участка

;второй участок - горизонталь правого луча
;посчитаем крайний правый Х
fld cos18 ;cos(18)
fimul radius ;R*cos(18)
fistp x2 ;х2=R*cos(18)

X2Loop:
fild num ;x
fst [POINT ptr di].X0 ;сохраним, как (float)x0
fstp [POINT ptr di].Xi ;и как начальный x
mov [POINT ptr d i].FY, offset CalcY2
;расчитаем приращение по Х для морфинга по лучам из (0,0)
call CalcDelta, N, radius
add di, size POINT ;на следующую точку
inc num ;x=x+1
mov ax, num ;дошли ли до конца луча?
cmp ax, x2
jbe X2Loop ;по всем точкам второго участка

;третий участок - нижний отрезок правого луча
;посчитаем Х конца отрезка
fld sin18 ;sin(18)
fimul c2 ;2*sin(18)
fld1 ;1
faddp ;1+2*sin(18)
fmul fx1 ;х1*(1+2*sin(18))
fistp x2 ;x2=х1*(1+2*sin(18))

dec num ;вернемся на последнюю точку
X3Loop:
dec num ;возвращаемся назад по другому отрезку
mov ax, num
cmp ax, x2 ;дошли до конца отрезка?
jb X4Start
fild num ;x
fst [POINT ptr di].X0 ;сохраним, как (float)x0
fstp [POINT ptr di].Xi ;и как начальный x
mov [POINT ptr di].FY, offset CalcY3
call CalcDelta, N, radius
add di, size POINT ;на следующую точку
jmp X3Loop ;по всем точкам третьего участка

;четвертый участок - правый отрезок нижнего луча
;посчитаем Х конца отрезка
X4Start:
fld sin18 ;sin(18)
fld1 ;1
faddp ;1+s in(18)
fimul c2 ;2*(1+sin(18))
fmul fx1 ;x1*(2*(1+sin(18)))
fistp x2 ;x2=x1*(2*(1+sin(18)))

inc num ;вернемся на последнюю точку
X4Loop:
inc num ;идем по другому отрезку
mov ax, num
cmp ax, x2 ;дошли до конца отрезка?
ja X5Start
fild num ;x
fst [POINT ptr di].X0 ;сохраним, как (float)x0
fstp [POINT ptr di].Xi ;и как начальный x
mov [POINT ptr di].FY, offset CalcY1 ;функция такая же, т.к. та же прямая
call CalcDelta, N, radius
add di, size POINT ;на следующую точку
jmp X4Loop ;по всем точкам четвертого участка

;пятый участок - левый отрезок нижнего луча
X5Start:
dec num ;вернемся на последнюю точку
X5Loop:
dec num ;идем по последнему отрезку
cmp num, 0
jl FPRet ;до 0
fild num ;x
fst [POINT ptr di].X0 ;сохраним, как (float)x0
fstp [POINT ptr di].Xi ;и как начальный x
mov [POINT ptr di].FY, offset CalcY4
call CalcDelta, N, radius
add di, size POINT ;на следующую точку
jmp X5Loop ;по всем точкам второго участка
FPRet:
mov LAddr, di ;сохраним адрес для проверки конца
; sub di, size POINT
; fld [POINT ptr di].X0
; mov ax, [POINT ptr di].FY
; call ax
; add ax, radius
; mov num, ax
; fild num
; mov num, N
; fidiv num
; fstp [POINT ptr di].Xd
ret
FormPoints endp

;Расчет приращения по Х для морфинга
;Параметры: число итераций морфинга и радиус окружности
;di - адрес структуры POINT
;DeltaX = (R/(sqrt(x0^2+y0^2)-1)*x0
CalcDelta proc, Count:word, CircusRadius:word
local yyy:word ;переменная для обмена данными с сопроцессором
fld [POINT ptr di].X0 ;Х0 точки на звезде
fld st ;сохраним в стеке для дальнейших вычислений
fld st
fld st
fmulp ;st=x0*x0
fxch ;st=x0, st(1)=x0*x0
mov ax, [POINT ptr di].FY ;функция вычисления y
call ax ;ax=y0=y(x0)
mov yyy, ax ;сохраним
fild yyy ;y0
fld st ;st(1)=st=y0
fmulp ;y0*y0
faddp ;x0*x0+y0*y0
fsqrt ;sqrt(x0*x0+y0*y0)
fild CircusRadius ;радиус
fdivrp ;R/sqrt(x0*x0+y0*y0)
fld1 ;1
fsubp ;R/sqrt(x0*x0+y0*y0) - 1
fmulp ;x0*(R/sqrt(x0*x0+y0*y0) - 1) - длина добавки по Х
fidiv Count ;разделим на число итераций
fstp [POINT ptr di].Xd ;сохраним приращение по Х
ret
CalcDelta endp

;Вычисление Y для очередной итерации морфинга
;Точки строятся на продолжениях лучей из (0,0) до (x0,y0),
; где (x0,y0) - точки на звезде
;y = x * y0 / x0
CalcY proc
local yyy:word
;проверим, равен ли нулю x0, иначе будет деление на 0
cmp [POINT ptr di].X0, 0
je ForXeq0
fld [POINT ptr di].X0 ;x0
fld st ;st=st(1)=x0
call ax ;ax=y0=y(x0)
mov yyy, ax
fild yyy ;st=y0
fdivrp ;st=y0/x0
fmulp ;st=x*y0/x0
fistp yyy
mov ax, yyy ;ax=y=[x*y0/x0]
jmp CYRet
ForXeq0:
call ax ;для x0=0 ax=y0=y(x0)
CYRet:
ret
CalcY endp

;Функци и расчета y0 для участков звезды
;st = x0
;результат - целое в ax
CalcY1 proc ;первый участок
local yyy:word
mov yyy, R< br> fdiv tg18
fild yyy
fsubrp
fistp yyy
mov ax, yyy ;ax=y0=R-x0/tg(18)
ret
CalcY1 endp

CalcY2 proc ;второй участок
local yyy:word
fistp yyy
mov yyy, R
fild yyy
fsub fy1
fistp yyy
mov ax, yyy ;ax=y0=R-y1
ret
CalcY2 endp

CalcY3 proc ;третий участок
local yyy:word
fmul tg36
fld fx1
fdiv sin36
fsubp
fistp yyy
mov ax, yyy ;ax=y0=x0*tg(36)-x1/sin(36)
ret
CalcY3 endp

CalcY4 proc ;четвертый участок
local yyy:word
fdiv tg54
fchs
fld fx1
fdiv sin36
fsubp
fistp yyy
mov ax, yyy ;ax=y0=-x0/tg(54)-x1/sin(36)
ret
CalcY4 endp

;Вывод одной итерации цветом colour
PrintFigure PROC colour:word
uses cx
local X1Num:word,Y1num:word,X2Num:word,Y2num:word,RR:word
mov RR, R ;радиус для вычислений
lea di, pPoints ;адрес массива точек
mov bx, size POINT ;длина одного элемента
neg bx ;будем адресовать предыдущий э лемент

;получаем координаты первой точки
fld [POINT ptr di].Xi ;Хi
fist X1Num ;X1=Xi
mov ax, [POINT ptr di].FY
call CalcY ;ax = FY(X1)
mov Y1Num, ax ;Y1 = ax
PrintLoop:
add di, size POINT ;на следующую точку
mov ax, LAddr ;отрабатываем до предпоследней точки!
sub ax, size POINT
cmp di, ax
jae PFRet
;получаем координаты второй точки
fld [POINT ptr di].Xi ;Xi
fist X2Num ;X2=Xi
mov ax, [POINT ptr di].FY
call CalcY ;ax = FY(X2)
mov Y2Num, ax ;Y2 = ax

;выводим отрезок в правой половине
push colour ;цвет
mov ax, 100
sub ax, Y2Num ;Y2 выше центра
push ax
mov ax, 160
add ax, X2Num ;X2 справа центра
push ax
mov ax, 100
sub ax, Y1Num ;Y1 выше центра
push ax
mov ax, 160
add ax, X1Num ;X1 справа центра
push ax
call line
add sp, 5*2

;выводим отрезок в левой половине
push colour ;цвет
mov ax, 100
sub ax, Y2Num ; Y2 выше центра
push ax
mov ax, 160
sub ax, X2Num ;X2 слева центра
push ax
mov ax, 100
sub ax, Y1Num ;Y1 выше центра
push ax
mov ax, 160
sub ax, X1Num ;X1 слева центра
push ax
call line
add sp, 5*2

;копируем правую точку (x2,y2) на место первой (x1,y1) для следующего отрезка
mov ax, X2Num
mov X1Num, ax
mov ax, Y2Num
mov Y1Num, ax

cmp colour, 0 ;после вытирания цветом 0 сдвигаем Xi на DeltaX
jne PrintLoop
fld [POINT ptr di+bx].Xi ;перейдем к следующей точке
fadd [POINT ptr di+bx].Xd
fstp [POINT ptr di+bx].Xi ;Xi=Xi+Xd
jmp PrintLoop
PFRet:
cmp colour, 0 ;после вытирания цветом 0 сдвигаем Xi на DeltaX
jne PFrr
fld [POINT ptr di+bx].Xi ;перейдем к следующей точке
fadd [POINT ptr di+bx].Xd
fstp [POINT ptr di+bx].Xi ;Xi=Xi+Xd
PFrr: ;соединим концы горизонтальной линией
push colour ;цвет
mov ax, 100
sub ax, Y1Num ;Y2 выше центра
pu sh ax
mov ax, 160
sub ax, X1Num ;X2 слева центра
dec ax
push ax
mov ax, 100
sub ax, Y1Num ;Y1 выше центра
push ax
mov ax, 160
add ax, X1Num ;X1 справа центра
push ax
call line
add sp, 5*2

ret
PrintFigure 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&l t;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 ;загружаем управляющее слово
frndint ;округляем st до целого
fclex ;сбросим исключения
fldcw CtrlWordOld ;восстановим старое управляющее слово
ret
floor endp

;пауза ~40мс. Под Windows весьма условно, скорее всего будет больше
time equ 4 ;число интервалов по 10мс
DELAY: pusha ;сохраним все рег истры
mov ah,2dh ;сбросим "локальное" системное время (под nt+ все равно не поменяет)
xor cx,cx
xor dx,dx
int 21 h

dl2: mov ah,2ch
int 21h ;читаем время
;считаем сотни мс
mov al,100
mul dh ;секунды умножаем на 100 -> ax = количество интервалов по 10мс
xor dh,dh ;dx - число сотых
xchg ax,dx ;поменяем местами
mov cl,10
div cl ;ax = количество интервалов по 10мс из сотых
add ax,dx ;складываем с количеством из секунд
cmp ax,time ;сравним с ожидаемым интервалом
jl dl2 ;ждем, если меньше
popa ;восстановим все регистры
ret

.data
;константы для вычислений
c2 dw 2 ;при умножении на 2
c18 dw 18 ;18 градусов
c36 dw 36 ;36 градусов
c54 dw 54 ;54 градусов
c180 dw 180 ;180 градусов для перевода в радианы

.data?
LAddr dw ? ;адрес конца массива точек
sin18 dd ? ;float для хранения sin(18)
cos18 dd ? ;float для хранения cos(18)
tg18 dd ? ;float для хранения tg(18)
fx1 dd ? ;Х конца первого отрезка
fy1 dd ? ;Y конца первого отрезка
sin36 dd ? ;float для хранения sin(36)
tg36 dd ? ;floa t для хранения tg(36)
tg54 dd ? ;float для хранения tg(54)
pPoints label DWORD ;с этого адреса будем хранить данные о точках

end

-----
Удачи!

Ответ отправил: Лысков Игорь Витальевич, Модератор
Ответ отправлен: 31.05.2010, 01:58
Номер ответа: 261769
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru
Абонент Skype: igorlyskov

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 261769 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Вопрос № 178653:

    помогите пожалуйста,эксперты!есть код программы,но проблема в том что значения записываются во внутреннюю память,а нужно чтобы записывались во внешнюю память!

    name var3
     
    DSEG    AT  30h               
    CSEG    AT   0h
     
    jmp main
     
    Array: dw 0FEh, 0FDh, 0FCh, 0EDh, 0FAh, 0FFh, 0F9h, 0EFh, 0EEh, 0FBh
     
    main:
    mov dptr, #Array
    mov r0, #10
    clr a
    mov r1, a
    mov r2, a
    mov r3, a
     
    clr          c                    
    mov      a, #1             
    movc    a, @a + dptr
    mov      r1, a 
     
    round:
    djnz r0, Toonel
    jmp exit
    Toonel:
    clr c           
    clr         a
    mov r2, a
    mov r3, a
    inc dptr
    inc dptr
     
    mov      a, #1              
    movc    a, @a + dptr
    mov     r2, a
     
    subb a, r1
    mov r3, a
    JC round
     
    clr a
    mov a, r2
    mov r1, a
    jmp round
    exit:
    NOP
    END

    Отправлен: 26.05.2010, 01:31
    Вопрос задал: bass, Посетитель
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич, Модератор :
    Здравствуйте, bass.
    Предлагаю Вам свое решение:
    Код:
    ExtMem equ 0  ;адрес внешней памяти для найденного максимального значения
    max equ 8 ;временное максимальное значение
    Stack equ 60h ;стек

    org 9000h ;адрес начала программы
    main:
    mov sp,#Stack ;задаем вершину стека

    mov dptr,#Array ;адрес массива байт
    mov r2,#Len ;длина массива
    mov max,#0 ;максимум
    mov r4,#0 ;индекс в массиве
    loop: ;цикл поиска максимума
    mov a,r4 ;индекс
    movc a,@a + dptr ;читаем очередной байт

    cjne a,max,cmp_max ;сравниваем, если не равно, то на метку
    jmp next ;если равно, то на следующий байт
    cmp_max:
    jc next ;если очередной байт < max, то на следующий
    mov max, a ;иначе сохраняем, как максима льный
    next: ;на следуэщий байт
    inc r4 ;готовим индекс для следующего
    djnz r2,loop ;r2=r2-1, циклим, пока r2!=0

    mov dptr,#ExtMem ;адрес во внешней памяти, куда запишем результат
    mov a,max ;максимальное значение
    movx @dptr,a ;сохраняем

    jmp $ ;бесконечный цикл на месте

    Array dw 0FEh,0FDh,0FCh,0EDh,0FAh,0FFh,0F9h,0EFh,0EEh,0FBh
    Len equ $-Array ;длина массива

    END

    -----
    Удачи!

    Ответ отправил: Лысков Игорь Витальевич, Модератор
    Ответ отправлен: 26.05.2010, 02:42
    Номер ответа: 261649
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru
    Абонент Skype: igorlyskov

    Оценка ответа: 5

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 261649 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Вопрос № 178661:

    Здравствуйте уважаемые эксперты! Требуется решить такую задачку:

    Составить программу, выводящую на экран и в задаваемый с клавиатуры файл десятичное представление двойного факториала. Должна быть работоспособна для вычисления 1000!!. Число тоже нужно задавать с клавиатуры с контролем ввода.

    Двойной факториал, это например:

    Если число четное, то двойной факториал будет: 2*4*6*8...
    Если нечетное, то: 1*3*5*7...

    Есть идея как сделать, чтоб было без проверки на четность и нечетность. Нужно взять введенное число и вычислять факториал с конца, например, если 10, то 10*8*6*4*2, т.е. loop до 2. Прошу написать программу с подробными комментарями, та как мне придется объяснять как она работает! (Желательно с описанием алгоритма!) Заранее спасибо!

    Отправлен: 26.05.2010, 06:02
    Вопрос задал: Петров Юрий Иванович, Посетитель
    Всего ответов: 1
    Страница вопроса »


    Отвечает amnick, Студент :
    Здравствуйте, Петров Юрий Иванович.

    Небольшой поиск по сайту дает ссылку на очень похожий вопрос 155765. В приведенном там решении Зенченко Константина Николаевича длинное число хранится в массиве поразрядно с основанием системы счисления 10.

    Представление длинных чисел как массива отдельных цифр является стандартным подходом, различается только основание системы счисления. Для повышения эффективности вычислений и экономии памяти основание системы счисления следует выбирать возможно большим. Однако, если оно не кратно 10, то усложняется ввод и вывод чисел в обычном строковом представлении.

    В приложении приведено решение с основанием системы счисления 10000 (для 16-битного CPU), т.е. в каждом разряде хранится не одна, а 4 десятичных цифры. Если использовать 32-битные регистры, то основание системы счисления можно увеличить.

    Подробно можно почитать в статье "Длинная арифметика" (В.Гольдштейн).

    Использовался TASM. Компилировать в COM-файл.

    Успехов!

    Приложение:

    Ответ отправил: amnick, Студент
    Ответ отправлен: 26.05.2010, 18:10
    Номер ответа: 261685

    Оценка ответа: 5
    Комментарий к оценке:
    Спасибо огромное! Программа работает и написана отлично, все с комментариями) Похожий вопрос 155765 я видел и пробовал в нем разбираться, но алгоритма до конца не понял, пытался поменять шаг на 2, но не нашел где! И спасибо за подробное описание, буду разбираться)

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 261685 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Вопрос № 178664:

    Вычислить значение выражения Ax^2+Bx+C на интервале [Xmin; Xmax] с шагом 1. Вывести аргумент и значение функции в виде таблицы. Организовать вывод ФИО, уникального номера, текущего системного времени и даты.
    Xmin=3 Xmax=7 A=1 B=3 C=2

    Процессор - 8086
    Ассемблер - TASM v. 2.51
    Платформа - MS-DOS
    Модель памяти - не имеет значения

    Сам написал код (немного помог Лысков Игорь Витальевич). Закавыка в том, что неправильно выводится дата, а именно год. Оформлял кусок вывода даты в виде отдельной программы - все работает правильно. Помогите найти ошибку.

    Отправлен: 26.05.2010, 16:49
    Вопрос задал: Никифоров Павел, Посетитель
    Всего ответов: 1
    Страница вопроса »


    Отвечает Airyashov, Студент :
    Здравствуйте, Никифоров Павел.
    push cx неверно написано наверное 'С' русская, здесь
    Код:
    PUSH СX  ; сохраняем год в стеке
    PUSH DX ; сохраняем месяц и день в стеке

    также используется 'C' - это зарезервированное слово

    Ответ отправил: Airyashov, Студент
    Ответ отправлен: 26.05.2010, 17:10
    Номер ответа: 261682

    Оценка ответа: 1
    Комментарий к оценке:
    Если бы было русское C, это отловил бы транслятор. Учите матчасть.

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 261682 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Вопрос № 178666:

    Здравствуйте уважаемые эксперты!

    Помогите пожалуйста решить задачу, имеется строка - предложение из нескольких слов. Написать процедуру, осуществляющую запись тех же строк словами, переписанными с конца наперед. Дополнительных массивов не использовать. Исходная строка вводится с клавиатуры. Задача под TASM 16 бит.

    Например, исходная строка:
    привет мир

    В результате должно получиться:
    тевирп рим

    С ассемблером в плохих отношениях, поэтому нужны подробные комментарии и объяснения.

    Отправлен: 26.05.2010, 18:52
    Вопрос задал: Петров Юрий Иванович, Посетитель
    Всего ответов: 1
    Страница вопроса »


    Отвечает amnick, Студент :
    Здравствуйте, Петров Юрий Иванович.

    Программа с комментариями — в приложении. Требуемая по условию процедура — invert_words_in_string.
    Компилировать в COM-файл.
    Если есть вопросы, то обращайтесь в мини-форум.

    Успехов!

    Приложение:

    Ответ отправил: amnick, Студент
    Ответ отправлен: 26.05.2010, 20:50
    Номер ответа: 261687

    Оценка ответа: 5
    Комментарий к оценке:
    Спасибо! Вы мне очень помогли)

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 261687 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.16 от 26.05.2010

    В избранное