boly
Гость
|
|
« : 01-06-2009 15:46 » |
|
Дали задание: Есть массив М = {15, 1, 3, 7, -2, 6, 12, 10, 9, 3}, есть функция Y=(m1-m2)x + (m2-m3)2x + ... + (m9 - m10)9x, коэффициент x=2, с клавиатуры вводится, сколько раз складывать (m1-m2)x + (m2-m3)2x + ... Почти все работает, только неправильно складывает, точнее, правильно складывает первые 2 раза, а потом какая-то фигня, пробовал менять числа в массиве, был замечен косяк, что неправильно складывает, когда меняется число разрядов или знак промежуточного результата - что-то типа того гляньте, может, найдете ошибку.. model small .data mas db 15,1,3,7,-2,6,12,10,9,3,'$' ;Инициализируем массив. Размер каждого элемента байт test db 15, '$' nl db 10, 13, '$' .stack 256 .code
prntn proc push bx push cx mov dh, 0 mov cx, 1 mov bx, 10
cmp ax, 0 jg dloop neg ax mov bx, ax mov dl, '-' mov ah, 2 int 21h mov ax, bx mov bx, 10
dloop: cbw cmp al,9 jbe dloope
div bl mov dl, ah push dx inc cx ja dloop
dloope: mov dl, al push dx
lprn: pop dx add dx, '0' mov ah, 2 int 21h loop lprn
mov ah, 9 mov dx, offset nl int 21h
pop cx pop bx ret prntn endp
main proc
mov ax,@data mov ds,ax
xor ax,ax xor dl,dl
mov ah,1 int 21h mov dl,al and ax,0fh
lea bx,mas
xor cx,cx mov cx,ax mov ax,cx and ax,0fh xor ax,ax push ax xor dx,dx mov dl,1 push dx
@1: xor dx,dx mov al,[bx] mov dl,[bx+1] sub al,dl pop dx xor bx,bx mov bl,dl add bl,1 push ax ;(a1-a2->stack) xor ax,ax mov al,dl mov dl,2 imul dl mov dx,ax pop ax imul dl
pop dx add dx,ax push dx push bx ;call prntn xor ax,ax xor bx,bx mov al,[bx] inc bx loop @1
pop bx pop ax call prntn
;xor ax,ax ;mov al, mas
mov ax,4c00h int 21h
main endp end main
|
|
« Последнее редактирование: 01-06-2009 16:27 от Sel »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 02-06-2009 16:49 » |
|
boly, запутано как-то получилось... Математически такой ряд легче описать (и проще потом понять) подобной формулой: y = Σ nx(m(n)-m(n+1))В данном случае у нас n = 1..9. model small
.code
my_formula proc ; Описывать входные и выходные параметры должно быть правилом. ; IN: al = x, si = адрес массива ; OUT: ax = результат
; Полезная практика - не изменять регистров. push bx push cx push dx push si push di push bp
movsx bx, al ; Знаково расширяем до слова значение "x" и сохраняем в bx. Это будет хранилищем n * x. mov bp, bx ; Сохраняем "x".
mov cx, 9 ; Число итераций. ; Можно было бы не устанавливать его здесь, а сделать входным параметров. ; Тогда можно будет вычислять ряды других размеров.
xor di, di ; Инициализируем накопитель результата.
lodsb ; Считываем первое значение и расширяем до слова. movsx dx, al
@1: lodsb ; Считываем следующее значение и расширяем до слова. movsx ax, al
sub dx, ax ; (m[n] - m[n+1]) imul dx, bx ; n * x * (m[n] - m[n+1]) add di, dx ; Суммируем результат.
mov dx, ax ; В dx хранится предыдущее читанное значение.
add bx, bp ; (n + 1) * x
loop @1 ; Команда loop использует cx в качестве обратного счетчика.
mov ax, di ; Результат.
; Восстанавливаем входные значения. pop bp pop di pop si pop dx pop cx pop bx ret my_formula endp
Примерно так. Код не проверял. Некоторые команды появились только в 386: movsx и более гибкая форма imul. Не вижу смысла избегать этих команд, т.к. найти такой процессор, который не сможет это исполнить, будет очень сложно. Единственное исключение - микроконтроллер 186. А для самостоятельного размышления тебе задачка (препод наверняка спросит): почему выходной результат выбран размером в 16 бит.
|
|
« Последнее редактирование: 02-06-2009 16:56 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
boly
Гость
|
|
« Ответ #2 : 02-06-2009 19:22 » |
|
проблема в том что это все делается на тасме и походу он ничего не понимает..
I:\study\Ассемблер\Ассемблер для СМ>tasm eho.asm Turbo Assembler Version 2.0 Copyright (c) 1988, 1990 Borland International
Assembling file: eho.asm **Error** eho.asm(18) Illegal instruction for currently selected processor(s) **Error** eho.asm(28) Illegal instruction for currently selected processor(s) **Error** eho.asm(32) Illegal instruction for currently selected processor(s) **Error** eho.asm(35) Extra characters on line **Fatal** eho.asm(55) Unexpected end of file encountered Error messages: 5 Warning messages: None Passes: 1 Remaining memory: 476k
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #3 : 02-06-2009 19:56 » |
|
Добавь в начало директиву:
.486
Ну а "Unexpected end of file encountered" вполне понятно - я же только процедуру расчета привел, а не полный код программы.
|
|
« Последнее редактирование: 02-06-2009 20:02 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
boly
Гость
|
|
« Ответ #4 : 03-06-2009 16:48 » |
|
тока я не понял а куда мы масив-то запивываем? у меня это было:
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #5 : 03-06-2009 18:08 » |
|
boly, неужели не понятно? Я написал и разжевал тебе алгоритм. Программа у тебя уже была. Сделай из них одно целое.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
boly
Гость
|
|
« Ответ #6 : 16-06-2009 18:19 » |
|
никак не получается выдает сперва неверный ответ, а за ним кучу иероглифов...посмотрите плз model small .486 .data mas db 15,1,3,7,-2,6,12,10,9,3,'$' ;Инициализируем массив. Размер каждого элемента байт ;test db 15, '$' nl db 10, 13, '$' .stack 256 .code
prntn proc push bx push cx mov dh, 0 mov cx, 1 mov bx, 10
cmp ax, 0 jg dloop neg ax mov bx, ax mov dl, '-' mov ah, 2 int 21h mov ax, bx mov bx, 10
dloop: cbw cmp al,9 jbe dloope
div bl mov dl, ah push dx inc cx ja dloop
dloope: mov dl, al push dx
lprn: pop dx add dx, '0' mov ah, 2 int 21h loop lprn
mov ah, 9 mov dx, offset nl int 21h
pop cx pop bx ret prntn endp
main proc
mov ah,1 int 21h mov dl,al and ax,0fh
lea si,mas mov al,2
; Описывать входные и выходные параметры должно быть правилом. ; IN: al = x, si = адрес массива ; OUT: ax = результат
; Полезная практика - не изменять регистров. push bx push cx push dx push si push di push bp
movsx bx, al ; Знаково расширяем до слова значение "x" и сохраняем в bx. Это будет хранилищем n * x. mov bp, bx ; Сохраняем "x".
mov cx, dx ; Число итераций.
; Можно было бы не устанавливать его здесь, а сделать входным параметров. ; Тогда можно будет вычислять ряды других размеров.
xor di, di ; Инициализируем накопитель результата.
lodsb ; Считываем первое значение и расширяем до слова. movsx dx, al
@1: lodsb ; Считываем следующее значение и расширяем до слова. movsx ax, al
sub dx, ax ; (m[n] - m[n+1]) imul dx, bx ; n * x * (m[n] - m[n+1]) add di, dx ; Суммируем результат.
mov dx, ax ; В dx хранится предыдущее читанное значение.
add bx, bp ; (n + 1) * x
loop @1 ; Команда loop использует cx в качестве обратного счетчика.
mov ax, di ; Результат.
call prntn
; Восстанавливаем входные значения. pop bp pop di pop si pop dx pop cx pop bx ret
mov ax,4c00h int 21h
main endp end main
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #7 : 16-06-2009 19:25 » |
|
boly, скажи пожалуйста, для чего ты ставишь в конце блока данных символ доллара? Меня это очень интересует. Мне кажется, что учиться ты не хочешь...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
boly
Гость
|
|
« Ответ #8 : 16-06-2009 19:40 » |
|
дело в том, что лабораторки у нас были на паскале, и на ассемблере мы делали только какие-то элементарные вкрапления, а под конец дали задание где нужно целиком все на асме сделать и ограничение для цикла, и массив задать, и функцию реализоватиь, а материала нифига нет, вот и приходится цеплять отовсюду кусками, символ доллара я увидел где-то так масиив задавался подставил в свою прогу - заработало да не до конца.. а с предложенной вами реализацией функции не правильно считает вот и спрашиваю может вы найдете ошибку..
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #9 : 16-06-2009 19:55 » |
|
boly, а когда ты пойдешь работать, то тоже будешь говорить, что это на лабораторках не проходили? За такой подход будешь получать три копейки, а чтобы заработать на полноценный обед из трех блюд, придется напрячься и самостоятельно искать и изучать материал, а потом тренироваться и еще раз тренироваться. Сейчас же тебе все дают бесплатно, да еще и стипендию платят. Т.ч. учись пока есть возможность! Что не было на занятиях ты вполне можешь изучить самостоятельно. Еще одна важная мысль: в ВУЗе надо учиться обучаться, а не учиться списывать — спустя годы перестроить мозги будет значииииительно труднее. Для сведения: константа '$' - символ доллара - используется некоторыми функциями MSDOS для указания конца текстовой строки. Никакого другого сакрального смысла в нем нет. Писать за тебя программу я не буду (и, как видишь, больше тоже никто не горит желанием) — вполне достаточно того, что я тебе написал ту часть, которая отвечает за логику твоего задания. Остальное изучай сам. Будешь учиться — поможем, а халявы не жди. Рекомендую скачать программу-справочник по функциям MSDOS и BIOS — может пригодится для лучшего понимания. Тут: https://club.shelek.ru/viewfiles.php?id=3Называется Tech Help! 4.0.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|