Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблема со сложением в цикле.  (Прочитано 12098 раз)
0 Пользователей и 1 Гость смотрят эту тему.
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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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 » 

тока я не понял а куда мы масив-то запивываем? у меня это было:
Код:
lea bx,mas
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 16-06-2009 19:25 » 

boly, скажи пожалуйста, для чего ты ставишь в конце блока данных символ доллара? Меня это очень интересует.

Мне кажется, что учиться ты не хочешь... Жаль
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
boly
Гость
« Ответ #8 : 16-06-2009 19:40 » 

дело в том, что лабораторки у нас были на паскале, и на ассемблере мы делали только какие-то элементарные вкрапления, а под конец дали задание где нужно целиком все на асме сделать и ограничение для цикла, и массив задать, и функцию реализоватиь, а материала нифига нет, вот и приходится цеплять отовсюду кусками, символ доллара я увидел где-то так масиив задавался подставил в свою прогу - заработало да не до конца.. а с предложенной вами реализацией функции не правильно считает вот и спрашиваю может вы найдете ошибку..
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 16-06-2009 19:55 » new

boly, а когда ты пойдешь работать, то тоже будешь говорить, что это на лабораторках не проходили? За такой подход будешь получать три копейки, а чтобы заработать на полноценный обед из трех блюд, придется напрячься и самостоятельно искать и изучать материал, а потом тренироваться и еще раз тренироваться. Сейчас же тебе все дают бесплатно, да еще и стипендию платят. Т.ч. учись пока есть возможность! Что не было на занятиях ты вполне можешь изучить самостоятельно. Еще одна важная мысль: в ВУЗе надо учиться обучаться, а не учиться списывать — спустя годы перестроить мозги будет значииииительно труднее.

Для сведения: константа '$' - символ доллара - используется некоторыми функциями MSDOS для указания конца текстовой строки. Никакого другого сакрального смысла в нем нет.

Писать за тебя программу я не буду (и, как видишь, больше тоже никто не горит желанием) — вполне достаточно того, что я тебе написал ту часть, которая отвечает за логику твоего задания. Остальное изучай сам. Будешь учиться — поможем, а халявы не жди.

Рекомендую скачать программу-справочник по функциям MSDOS и BIOS — может пригодится для лучшего понимания.
Тут: https://club.shelek.ru/viewfiles.php?id=3
Называется Tech Help! 4.0.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines