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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 12.12.2012, 19:46   #1
dismayman
Новичок
Джуниор
 
Регистрация: 12.12.2012
Сообщений: 1
По умолчанию Вывод следующего, после введенной даты, дня

Ассемблер. Прошу указать на ошибки в программе. Задание было: запросить по отдельности номер дня, месяца и года. Вывести следующую дату - Д+1.
Программа вылетает после ввода года, подскажите в чем причина?
Тема http://www.programmersforum.ru/showt...F%F6+%E3%EE%E4 не помогла...
Код:
 model small
.data
den db 'Vvedite den: $'
mes db 'Vvedite mesac: $'
god db 'Vvedite god: $'
day db 'sled data: $'
.code
start:
mov AX, @data
mov DS, AX
mov DX, offset den
mov ah, 9
int 21h
call inputint
push ax

mov AX, @data
mov DS, AX
mov DX, offset mes
mov ah, 9
int 21h
call inputint
push ax

mov AX, @data
mov DS, AX
mov DX, offset god
mov ah, 9
int 21h
call inputint
push ax

pop dx
pop cx
pop bx

cmp cx, 4 ; april
jz d30 ; переход если в месяце 30 дней
cmp cx, 6 ; juny
jz d30
cmp cx, 9 ; september
jz d30
cmp cx, 11; november
jz d30

cmp cx, 1; january
jz d31 ; переход если в месяце 31 день
cmp cx, 3; mart
jz d31
cmp cx, 5; may
jz d31
cmp cx, 7; july
jz d31  
cmp cx, 8; august 
jz d31
cmp cx, 10; october
jz d31

cmp cx, 2; february
jz d28

cmp cx, 12; december
jz dnew

d30 proc
 cmp BX, 30
 jz dd30
dd30 proc; подпрограмма увеличения месяца и сброса дня
 MOV Bx, 0
 INC CX
 ret
dd30 endp
 INC BX; если дней не 30 то увеличиваем
 ret
d30 endp

d31 proc
 cmp BX, 31 ; если 31 день, то обнуляем день и месяц +1
 JZ dd31
dd31 proc; подрограмма сброса дня
 MOV BX, 0; первое число
 INC CX
 ret
dd31 endp
 inc BX; если дней не 31, то увеличиваем
 ret
d31 endp

d28 proc; подпрограмма февраля
 cmp BX, 28
 JZ dd28 ; если 28 дней февраля, то день = 1, месяц = 3
dd28 proc
 MOV BX,0
 MOV CX,3
 ret
dd28 endp
 INC BX
 ret
d28 endp

dnew proc; подпрограмма 31 декабря
 cmp BX,31
 jz ddnew
ddnew proc
 MOV BX,0
 MOV CX,1
 INC dx
 ret
ddnew endp
 INC BX
 ret
dnew endp

push dx
push cx
push bx

mov AX, @data
mov DS, AX
mov DX, offset day
mov ah, 9
int 21h

pop bx
mov ax, bx
call outint
pop bx
mov ax, bx
call outint
pop bx
mov ax, bx
call outint

OutInt proc
        
;; если число знаковое, то необходимо расскоментировать следующие строки
;; Проверяем число на знак.
;   test    ax, ax
;   jns     oi1
;
;; Если оно отрицательное, выведем минус и оставим его модуль.
;   mov  cx, ax
;   mov     ah, 02h
;   mov     dl, '-'
;   int     21h
;   mov  ax, cx
;   neg     ax
;; Количество цифр будем держать в CX.
;oi1:  
    xor     cx, cx
    mov     bx, 10 ; основание сс. 10 для десятеричной и т.п.
oi2:
    xor     dx,dx
    div     bx
; Делим число на основание сс. В остатке получается последняя цифра.
; Сразу выводить её нельзя, поэтому сохраним её в стэке.
    push    dx
    inc     cx
; А с частным повторяем то же самое, отделяя от него очередную
; цифру справа, пока не останется ноль, что значит, что дальше
; слева только нули.
    test    ax, ax
    jnz     oi2
; Теперь приступим к выводу.
    mov     ah, 02h
oi3:
    pop     dx
; Извлекаем очередную цифру, переводим её в символ и выводим.
;; раскоментировать если основание сс > 10, т.е. для вывода требуются буквы
;   cmp     dl,9
;   jbe     oi4
;   add     dl,7
;oi4:
    add     dl, '0'
    int     21h
; Повторим ровно столько раз, сколько цифр насчитали.
    loop    oi3
    
    ret
 
OutInt endp  

InputInt proc 
    mov ah,0ah
    xor di,di
    mov dx,offset buff ; аддрес буфера
    int 21h ; принимаем строку
    mov dl,0ah
    mov ah,02
    int 21h ; выводим перевода строки
; обрабатываем содержимое буфера
    mov si,offset buff+2 ; берем аддрес начала строки
    cmp byte ptr [si],"-" ; если первый символ минус
    jnz ii1
    mov di,1  ; устанавливаем флаг
    inc si    ; и пропускаем его
ii1:
    xor ax,ax
    mov bx,10  ; основание сc
ii2:
    mov cl,[si] ; берем символ из буфера
    cmp cl,0dh  ; проверяем не последний ли он
    jz endin
; если символ не последний, то проверяем его на правильность
    cmp cl,'0'  ; если введен неверный символ <0
    jl er
    cmp cl,'9'  ; если введен неверный символ >9
    ja er
 
    sub cl,'0' ; делаем из символа число 
    mul bx     ; умножаем на 10
    add ax,cx  ; прибавляем к остальным
    inc si     ; указатель на следующий символ
    jmp ii2     ; повторяем
er:   ; если была ошибка, то выводим сообщение об этом и выходим
    mov dx, offset error
    mov ah,09
    int 21h
    int 20h
; все символы из буфера обработаны число находится в ax
endin:
    cmp di,1 ; если установлен флаг, то
    jnz ii3
    neg ax   ; делаем число отрицательным
ii3:
    ret
error db "incorrect number$"
buff    db 6,7 Dup(?)
InputInt endp

         mov    AH,4Ch   ;  Функция 4Ch завершения программы
         mov    AL,00h   ;  Код 0 успешного завершения
         int    21h      ;  Вызов DOS

end start

Последний раз редактировалось dismayman; 13.12.2012 в 19:38.
dismayman вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Написать программу, которая вычисляет дату следующего дня Popeta Помощь студентам 10 04.04.2012 22:43
Oпределить значение переменных p после выполнения следующего фрагмента программы AndyMark Паскаль, Turbo Pascal, PascalABC.NET 16 19.12.2010 18:32
Вывод даты по году и номеру дня Fantom.as Общие вопросы C/C++ 4 04.12.2010 09:43
Нахождение следующего дня Plazma Общие вопросы C/C++ 0 27.11.2010 17:10
Определить значение переменной y после работы следующего фрагмента программы mastar Помощь студентам 7 09.04.2010 19:47