Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.01.2015, 19:30   #1
Devil669
Пользователь
 
Регистрация: 20.12.2011
Сообщений: 33
По умолчанию почему программа работает не правильно

Друзья, есть программа которая считает сумму положительных членов массива. Проблема в чем. На эеран выводится правильный ответ(42), а вот в переменную p записывается почему-то 20h(а это в dec 32). В чем дело?

Код:
.model small
.stack 100h
.data
     a db 1,2,3,4,5,6,-85,10,-9,11
     n equ 10
     p db '    ','$'
.code
     
     
     mov ax,@data
     mov ds,ax
     mov ax,0
     mov si,0
     mov cx,n
     ;*********
     ;Решение
     ;*********
label1:
      cmp a[si],0
      jnl label2
      inc si
      cmp si,n
      je c20
      loop label1
label2:
       add al,a[si]
       inc si
       cmp si,n
       je c21
       loop label1 


c21:
     mov cx,10
     lea si,p+3
c20: 
     cmp ax,10
     jb c30
     xor dx,dx
     div cx
     or dl,30h
     mov [si],dl
     dec si
     jmp c20
c30:
     or al,30h
     mov [si],al
     lea dx,p
     mov ah,9
     int 21h
Devil669 вне форума Ответить с цитированием
Старый 22.01.2015, 21:34   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Вы путаете. в переменную p записываются СИМВОЛЫ - там в данном случае НЕСКОЛЬКО ЦИФР (две), но длина переменной расчитана на 4-ре знака(цифры), поэтому там остаются два пробела.
20h - это ПРОБЕЛ.

скриншот показать?


p.s. а в конце программы надо дописать код завершения программы.
например:
Код:

     ; close program
     mov AX,4C00h
     int 21h
Serge_Bliznykov вне форума Ответить с цитированием
Старый 22.01.2015, 21:47   #3
Devil669
Пользователь
 
Регистрация: 20.12.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Вы путаете. в переменную p записываются СИМВОЛЫ - там в данном случае НЕСКОЛЬКО ЦИФР (две), но длина переменной расчитана на 4-ре знака(цифры), поэтому там остаются два пробела.
20h - это ПРОБЕЛ.

скриншот показать?


p.s. а в конце программы надо дописать код завершения программы.
например:
Код:

     ; close program
     mov AX,4C00h
     int 21h
Понятно. А как мне ответ вывести в переменную? Я бы сделал сам, просто я не совсем понимаю где в итоге эта сумма находится. В каком регистре?
Devil669 вне форума Ответить с цитированием
Старый 22.01.2015, 22:30   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

можно так:
Код:
.model small
.stack 100h
.data
     a db 1,2,3,4,5,6,-85,10,-9,11
     n equ 10
     p db '    ','$'
     summa dw 0
.code
     
start:     
     mov ax,@data
     mov ds,ax
     mov ax,0
     mov si,0
     mov cx,n
     ;*********
     ;Решение
     ;*********
label1:
     cmp a[si],0
     jl label2
     add al,a[si]
label2:
     inc si
     cmp si,n
     je c21
     loop label1 

; обработка результата
c21:
     mov  summa, ax  ; поместим значение суммы в переменную


     mov cx,10
     lea si,p+3
c22: 
     cmp ax,10
     jb c30
     xor dx,dx
     div cx
     or dl,30h
     mov [si],dl
     dec si
     jmp c22
c30:
     or al,30h
     mov [si],al
     lea dx,p
     mov ah,9
     int 21h

     ; close program
     mov AX,4C00h
     int 21h

end start

p.s. вообще то сумму накапливаем в регистре AL (кстати, опасно, легко за 255 перевалить! будет переполнение),
но, в связи с тем, что процедура вывода выводит содержимое регистра AX,
то я позволил себе переменную сумма сделать длиной слово (DW) и сохранить туда полностью регистр AX. Если Вам не нравится - то можно переделать на один байт и mov summa, al
Serge_Bliznykov вне форума Ответить с цитированием
Старый 22.01.2015, 22:38   #5
Devil669
Пользователь
 
Регистрация: 20.12.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение

p.s. вообще то сумму накапливаем в регистре AL (кстати, опасно, легко за 255 перевалить! будет переполнение),
но, в связи с тем, что процедура вывода выводит содержимое регистра AX,
то я позволил себе переменную сумма сделать длиной слово (DW) и сохранить туда полностью регистр AX. Если Вам не нравится - то можно переделать на один байт и mov summa, al
Круто, спасибо. Последний вопрос, раз вы хорошо разбираетесь. Зачем нужна переменная n? А, и еще один тогда, зачем мы вообще выводим символы в переменную p?
Devil669 вне форума Ответить с цитированием
Старый 22.01.2015, 23:02   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Последний вопрос, раз вы хорошо разбираетесь.
да не, не круто. Это мы тут резвимся, пока реальные спецы в тему не заглянули.

кстати, я ещё пару ненужных строчек в вашем коде проглядел:
Цитата:
Код:
label1:
     cmp a[si],0
     jl label2
     add al,a[si]
label2:
     inc si
     cmp si,n
     je c21
     loop label1
я выделил красным то, что можно смело выкинуть - всё будет без этих строк прекрасно работать!

Цитата:
Зачем нужна переменная n?
что бы знать, сколько же у нас в массиве всего чисел.
мы эту переменную используем в качестве счётчика цикла - чему равно n - столько раз и выполнится цикл проверки/сложения

Цитата:
еще один тогда, зачем мы вообще выводим символы в переменную p?
что отобразить число нужно его перевести в десятичный вид, годный для вывода на экран. Поэтому мы готовим пустую строчку, которая закачивается спец.символом - терминатором, кстати.
Потом делим наше число на 10, остатки от деления переводим в коды цифр (добавляем к значению числа 30h) и полученный СИМВОЛ помещаем в строку, при чём СПРАВА НАЛЕВО. получаем строчку, годную для вывода в консоль.

Ну, как-то так!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 22.01.2015, 23:26   #7
Devil669
Пользователь
 
Регистрация: 20.12.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
...
что отобразить число нужно его перевести в десятичный вид, годный для вывода на экран. Поэтому мы готовим пустую строчку, которая закачивается спец.символом - терминатором, кстати.
Потом делим наше число на 10, остатки от деления переводим в коды цифр (добавляем к значению числа 30h) и полученный СИМВОЛ помещаем в строку, при чём СПРАВА НАЛЕВО. получаем строчку, годную для вывода в консоль.

Ну, как-то так!
Раз на то пошло. Тоже самое только ситающая сумму отрицательных элементов. Не охота мне делать отдельную программу. Как вот это приладить в эту же программу, чтобы не запутаться с регистрами(которые заняты, которые нет) Надо ли создавать вторые переменные n и p? Или сделать чтобы сначала выполнялся один алгоритм потом все обнулять и выполнять второй. Не совсем понимаю как это организовать. Вот код(тоже самое только для орицательных).

Код:
.model small
.stack 100h
.data
     a db 1,2,3,4,5,6,-85,10,-9,11
     n equ 10
     p db '    ','$'
     summa dw 0
     summa1 dw 0
.code
     mov ax,@data
     mov ds,ax
     mov ax,0
     mov si,0
     xor bx,bx
     xor ax,ax
     lea dx,msg
     mov ah,9
     int 21h
     xor ax,ax
     mov cx,n
label1:
      cmp a[si],0
      jl label2
      inc si
      
      loop label1
label2:
       inc bl
       inc si
       loop label1   

 mov  summa1, bx
Devil669 вне форума Ответить с цитированием
Старый 23.01.2015, 00:01   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Надо ли создавать вторые переменные n и p?
нет, не надо.


Цитата:
Как вот это приладить в эту же программу, чтобы не запутаться с регистрами(которые заняты, которые нет) ... Или сделать чтобы сначала выполнялся один алгоритм потом все обнулять и выполнять второй.
Так это же Ассемблер! Тут Вы хозяин кода - как придумаете, так и будет (если не накосячите, конечно). И следить за тем, какие регистры где нужны и в каких что находится - ваша прямая обязанность. И какой алгоритм выбирать - то же Вам решать.
я бы в одном цикле замутил.


p.s. А это у Вас за код?! Так же куча ошибок! Он же вообще никакой суммы не находит!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 23.01.2015, 00:11   #9
Devil669
Пользователь
 
Регистрация: 20.12.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov;1462524


[I
p.s. А это у Вас за код?! Так же куча ошибок! Он же вообще никакой суммы не находит![/I]
Да, я затупил. Тут не сумма отрицательных считается, а их количество.
Devil669 вне форума Ответить с цитированием
Старый 23.01.2015, 00:17   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Devil669 Посмотреть сообщение
Да, я затупил. Тут не сумма отрицательных считается, а их количество.
Верно!
ну, значит. переделать на подсчёт суммы труда не составит?
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему код не правильно работает? Максим_maks Компоненты Delphi 0 21.01.2015 08:33
Почему не работает код, хотя вроде всё правильно mpdasa Помощь студентам 3 04.06.2012 10:44
Почему программа на С++ не работает с локальным описанием массива, но работает с глобальным? >>STINGER<< Помощь студентам 4 08.03.2011 09:56
Есть код но почему то не правильно работает -ushёl- Помощь студентам 1 10.05.2010 22:27
программа работает. правильно ли? getUp Общие вопросы C/C++ 10 26.03.2010 07:07