.MODEL Large
.data
SaveHourAndMinutes dw ?
SaveSecondAndSotiiDoliSecond dw ?
unset db 13,10,'$'
mes2 db ': $'
viv db ?
hour dw ?
minut dw ?
second dw ?
milisecond dw ?
.code
MOV Ah, 2cH
INT 21h
MOV SaveHourAndMinutes, Cx ;сохраняем значение часов и минут, которое было во время входа в программу
MOV SaveSecondAndSotiiDoliSecond, Dx ;сохраняем значение секунд и СОТЫХ долей миллисекунд, которое было во время входа в программу
SecundoMer:
INT 21h;
SUB Cx, SaveHourAndMinutes ;вычитаем из текущих часов и минут сохраненные
SUB Dx, SaveSecondAndSotiiDoliSecond;вычитаем из текущих секунд и сотых долей милисекунд сохраненные
;vivod:
MOV word ptr second, сl
LEA Dx, second
MOV ah,9h
INT 21h
END
Секундомер в TAsm
Код:
но этот код вместо секунд выводит какой-то бред. Как Я подозреваю, сделан неправильный вывод информации, т.к. в отладчике подсчет секунд, минут, часов выполняется нормально. Подскажите, как можно вывести значение отсчитанных секунд на экран и как из старшей(младшей) части регистров Cx и Dx можно извлечь в переменные числа
Код:
... Вывод second на экран ...
mov cx, 10
mov di, buffer + 5
mov al, "$"
stosb
mov ax, [second]
std
@@:
xor dx, dx
div cx
push ax
mov al, dl
add al, "0"
stosb
pop ax
test ax, ax
jnz @b
cld
mov dx, di
inc dx
mov ah, 9
int 0x21
... Где-то в области данных ...
buffer db 6 dup (?)
mov cx, 10
mov di, buffer + 5
mov al, "$"
stosb
mov ax, [second]
std
@@:
xor dx, dx
div cx
push ax
mov al, dl
add al, "0"
stosb
pop ax
test ax, ax
jnz @b
cld
mov dx, di
inc dx
mov ah, 9
int 0x21
... Где-то в области данных ...
buffer db 6 dup (?)
Ну а вообще то есть очень много способов преобразования числа в его строковое представление.
Код:
.MODEL Small
.STACK 100h
.DATA
SaveHourAndMinutes dw ?
SaveSecondAndSotiiDoliSecond dw ?
unset db 13,10,'$'
hungrid db 100
ten db 10
save db ?
ten2 dw 10
hour dw ?
minut dw ?
second dw ?
milisecond dw ?
.CODE
ORG 100h
SMART
LOCALS
include !mac.inc
Start:
MOV Ah, 2cH ;mov Ah, 2cH
INT 21h ;int 21h
;CH=часы
;CL=минуты
;DH=секунды
;DL=сотые доли секунды
MOV SaveHourAndMinutes, Cx ;сохраняем значение часов и минут, которое было во время входа в программу
MOV SaveSecondAndSotiiDoliSecond, Dx ;сохраняем значение секунд и СОТЫХ долей миллисекунд, которое было во время входа в программу
SecundoMer:
MOV Ah, 2cH
INT 21h;
CMP Dx, SaveSecondAndSotiiDoliSecond ;проверяем больше или нет текущее количество секунд, чем сохраненное
JGE WithoutDec
DEC Cl
ADD Dh, 60
WithoutDec:
SUB Cx, SaveHourAndMinutes ;вычитаем из текущих часов и минут сохраненные
SUB Dx, SaveSecondAndSotiiDoliSecond;вычитаем из текущих секунд и сотых долей милисекунд сохраненные
MOV Bx, Dx
MOV Ax, 3
INT 10h ;"чистим" экран
;ВЫВОД ОТСЧИТАННЫХ ЧАСОВ НА ЭКРАН И СОХРАНЕНИЕ ОТСЧИТАННЫХ МИНУТ
MOV Ax, Cx;
DIV hungrid
PUSH Ax ;сохраняем регистр Ax, в котором сейчас содержатся отсчитанные часы(Al) и минуты(Ah)
CBW ;расширяем байт
DIV ten ;делим отделенное количество часов на десять для вывода
MOV save, Ah ;сохраняем второе число в часах
MOV DL,AL
add DL,48
OutChar
MOV DL, save
add DL,48
OutChar
MOV DL,58 ;Вывод разделяющего двоеточия на экран
OutChar
;ВЫВОД ОТСЧИТАННЫХ МИНУТ НА ЭКРАН
POP Ax ;выгружаем из стека регистр Ax
MOV Al, Ah ;
CBW
DIV ten ;делим отделенное количество минут на десять для вывода
MOV save, Ah ;сохраняем второе число в минутах
MOV DL,AL
add DL,48
OutChar
MOV DL, save
add DL,48
OutChar
MOV DL,58 ;Вывод разделяющего двоеточия на экран
OutChar
;ВЫВОД ОТСЧИТАННЫХ СЕКУНД НА ЭКРАН
MOV Ax, Bx ;загружаем в Ax сохраненные секунды и миллисекунды
MOV Al, Ah ;перемещаем количество секунд в Al
aam ;делим Al на 10, остаток в Al, частное в Ah
MOV Dl, Ah
ADD Dl, 48
OutChar
MOV Dl, Al ;загружаем в Dl остаток от деления Al на 10
ADD Dl, 48
OutChar
Int 08H ;делаем несколько раз задержку на 54.9254 миллисекунд, т.к. иначе на экран при реальной работе программы не успевает ничего выводиться
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
jmp SecundoMer
_exit
END Start
.STACK 100h
.DATA
SaveHourAndMinutes dw ?
SaveSecondAndSotiiDoliSecond dw ?
unset db 13,10,'$'
hungrid db 100
ten db 10
save db ?
ten2 dw 10
hour dw ?
minut dw ?
second dw ?
milisecond dw ?
.CODE
ORG 100h
SMART
LOCALS
include !mac.inc
Start:
MOV Ah, 2cH ;mov Ah, 2cH
INT 21h ;int 21h
;CH=часы
;CL=минуты
;DH=секунды
;DL=сотые доли секунды
MOV SaveHourAndMinutes, Cx ;сохраняем значение часов и минут, которое было во время входа в программу
MOV SaveSecondAndSotiiDoliSecond, Dx ;сохраняем значение секунд и СОТЫХ долей миллисекунд, которое было во время входа в программу
SecundoMer:
MOV Ah, 2cH
INT 21h;
CMP Dx, SaveSecondAndSotiiDoliSecond ;проверяем больше или нет текущее количество секунд, чем сохраненное
JGE WithoutDec
DEC Cl
ADD Dh, 60
WithoutDec:
SUB Cx, SaveHourAndMinutes ;вычитаем из текущих часов и минут сохраненные
SUB Dx, SaveSecondAndSotiiDoliSecond;вычитаем из текущих секунд и сотых долей милисекунд сохраненные
MOV Bx, Dx
MOV Ax, 3
INT 10h ;"чистим" экран
;ВЫВОД ОТСЧИТАННЫХ ЧАСОВ НА ЭКРАН И СОХРАНЕНИЕ ОТСЧИТАННЫХ МИНУТ
MOV Ax, Cx;
DIV hungrid
PUSH Ax ;сохраняем регистр Ax, в котором сейчас содержатся отсчитанные часы(Al) и минуты(Ah)
CBW ;расширяем байт
DIV ten ;делим отделенное количество часов на десять для вывода
MOV save, Ah ;сохраняем второе число в часах
MOV DL,AL
add DL,48
OutChar
MOV DL, save
add DL,48
OutChar
MOV DL,58 ;Вывод разделяющего двоеточия на экран
OutChar
;ВЫВОД ОТСЧИТАННЫХ МИНУТ НА ЭКРАН
POP Ax ;выгружаем из стека регистр Ax
MOV Al, Ah ;
CBW
DIV ten ;делим отделенное количество минут на десять для вывода
MOV save, Ah ;сохраняем второе число в минутах
MOV DL,AL
add DL,48
OutChar
MOV DL, save
add DL,48
OutChar
MOV DL,58 ;Вывод разделяющего двоеточия на экран
OutChar
;ВЫВОД ОТСЧИТАННЫХ СЕКУНД НА ЭКРАН
MOV Ax, Bx ;загружаем в Ax сохраненные секунды и миллисекунды
MOV Al, Ah ;перемещаем количество секунд в Al
aam ;делим Al на 10, остаток в Al, частное в Ah
MOV Dl, Ah
ADD Dl, 48
OutChar
MOV Dl, Al ;загружаем в Dl остаток от деления Al на 10
ADD Dl, 48
OutChar
Int 08H ;делаем несколько раз задержку на 54.9254 миллисекунд, т.к. иначе на экран при реальной работе программы не успевает ничего выводиться
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
Int 08H
jmp SecundoMer
_exit
END Start
если запускать этот код через отладчик(дебаггер), то он отлично справляется с функцией секундомера, но если запускать EXE файл с этим кодом через ОС, то он даже не начинает выполняться - программа тут же "вылетает".
В работе использовал следующие макросы:
Код:
OutChar macro
push ax
mov ah,02h
int 21h
pop ax
endm
_Exit macro
mov ax,4c00h
int 21h
endm
push ax
mov ah,02h
int 21h
pop ax
endm
_Exit macro
mov ax,4c00h
int 21h
endm
Подскажите, из-за чего "вылетает" программа и как можно исправить? Как я предполагаю, эта проблема возникает из-за многократного использования прерывания INT 08h, но иначе при реальной работе программа очень быстро затирает время на экране и экран постоянно "пустой"
прерывание на rtc лучше ставить с настройками по всем параметрам 0x0ffh .
Код:
org 100h
jmp start
_lmsec db 0
_msec dd 0
_out_buff db 'sec: ',0xd,0x24
gettime:
mov ah,0x2c
int 21h
retn
calctime:
mov dh,dl
cmp dl,[_lmsec]
jae .@1
mov al,100
sub al,[_lmsec]
add dl,al
jmp .@2
.@1:
sub dl,[_lmsec]
.@2:
mov [_lmsec],dh
xor dh,dh
add word[_msec],dx
adc word[_msec+2],0
retn
convert:
mov si,_out_buff+15
xor ebx,ebx
mov bl,100
mov eax,[_msec]
xor edx,edx
div ebx
xchg ecx,eax
mov bl,10
mov eax,edx
.@1:
xor edx,edx
div ebx
add dl,48
mov [si],dl
dec si
test eax,eax
jnz .@1
cmp si,_out_buff+14
jb .@2
mov byte[si],48
dec si
.@2:
mov byte[si],46
dec si
xchg ecx,eax
.@3:
xor edx,edx
div ebx
add dl,48
mov [si],dl
dec si
test eax,eax
jnz .@3
.@4:
mov byte[si],32
dec si
cmp si,_out_buff+4
ja .@4
retn
print:
mov ah,9
mov dx,_out_buff
int 21h
retn
videomode:
mov ax,3
int 10h
retn
start:
push cs
pop ds
call videomode
call gettime
mov [_lmsec],dl
s_loop:
call gettime
call calctime
call convert
call print
jmp s_loop
jmp start
_lmsec db 0
_msec dd 0
_out_buff db 'sec: ',0xd,0x24
gettime:
mov ah,0x2c
int 21h
retn
calctime:
mov dh,dl
cmp dl,[_lmsec]
jae .@1
mov al,100
sub al,[_lmsec]
add dl,al
jmp .@2
.@1:
sub dl,[_lmsec]
.@2:
mov [_lmsec],dh
xor dh,dh
add word[_msec],dx
adc word[_msec+2],0
retn
convert:
mov si,_out_buff+15
xor ebx,ebx
mov bl,100
mov eax,[_msec]
xor edx,edx
div ebx
xchg ecx,eax
mov bl,10
mov eax,edx
.@1:
xor edx,edx
div ebx
add dl,48
mov [si],dl
dec si
test eax,eax
jnz .@1
cmp si,_out_buff+14
jb .@2
mov byte[si],48
dec si
.@2:
mov byte[si],46
dec si
xchg ecx,eax
.@3:
xor edx,edx
div ebx
add dl,48
mov [si],dl
dec si
test eax,eax
jnz .@3
.@4:
mov byte[si],32
dec si
cmp si,_out_buff+4
ja .@4
retn
print:
mov ah,9
mov dx,_out_buff
int 21h
retn
videomode:
mov ax,3
int 10h
retn
start:
push cs
pop ds
call videomode
call gettime
mov [_lmsec],dl
s_loop:
call gettime
call calctime
call convert
call print
jmp s_loop
Пишу следующий программный код:
Код:model large.stack 100h.data HowMouchAdd dd 54.9254 OneThousand dd 1000 Sixty dw 60; Zero dw 0 unset db 13,10, mes1 db : hour dw 0 minutes dw 0 second dw 0 milisecond dd 0.code;инициализируем сопроцессор, т.к. к milsecond будем прибавлять дробное число finit ;подключаем директиву 386 .386MilSek: INT 08h ;делаем прерывание на 54.9254 FLD milisecond; FLD HowMouchAdd; FADD FSTP milisecond; FLD milisecond; FCOMP OneThousand ;сравниваем milisecond с 1000 FSTSW Ax ;записываем слово-состояние в Ax AND Ax, 1000h ;затираем все биты Ax кроме бита, отвечающего за результат сравнения CMP Ax, 0000h; JZ MilSek ;если melisecond мень 1000, тогда переходим на метку MilSekSec: FLD milisecond; FSUB OneThousand FLD milisecond; ;milisecond=milisecond-1000 INC second; MOV Ax, Sixty ;заносим в регистр Ax число 60 CMP second, Ax ;сравниваем second с 60 JL Vivod ;если second<60, идем на метку VivodMin: MOV Ax, Zero ;заносим в Ax ноль MOV second, Ax ;second=0 INC minutes MOV Ax, Sixty CMP minutes, Ax ;сравниваем minutes с 60 JL Vivod ;если minutes<60, идем на метку VivodHours: MOV Ax, Zero MOV minutes, Ax ;заносим в minutes ноль INC hourVivod: lea dx,unset mov ah,9h int 21h ;переходим на новую строку lea dx,mes1 mov ah,9h int 21h ;ВЫВОД числа ;количество цифр будем хранить в cx xor cx,cx ;помещаем количество секунд в ax mov ax, second ;помещаем в bx десятку mov bx,10v1: ;делим число на десять xor dx,dx div bx ;помещаем остаток в стек push dx ;счетчик цифр в числе inc cx cmp ax,0 ;повторяем, пока число не станет нулём jne v1 ;теперь вывод mov ah,02hv2: ;извлекаем очередную цифру pop dx ;преобразуем в символ add dl,30h ;и выводим int 21h ;повторяем столько раз, сколько насчитали цифр loop v2ENDЭтот код почему-то уже на метке MilSek зацикливается. Возможно, я использую не правильную команду перехода. Подскажите пожалуйста, что нужно исправить, чтобы мой секундомер работал правильно?
Хотела бы вам посоветовать. (Не вкоем случае не настаиваю.)
Удивительный на мой взгляд сайт для женщин и мужчин. В моём профиле (заполняла при регистрации) Вы узнаете многие ответы на вопросы. Вот к примеру как, Похудение ну или любой другой .
Что это? Как это? И с чем это, а главное почему это так важно для женщины в современном обществе. Если у вас есть какие то полезные советы, наблюдения или Вы хотели бы задать вопрос на интерисующую вас тему? Милости просим, задaвайте, предлогайте, советуйте. Ведь для кого то это может принести пользу, кто то воспользуется именно Вашим советом и тем самым не попадет в неловкую ситуацию или еще хуже , даже страшно представить...
прошу прощения за опечатки....