Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/25: Рейтинг темы: голосов - 25, средняя оценка - 4.92
0 / 0 / 0
Регистрация: 02.11.2015
Сообщений: 57
TASM

Перехватив прерывание от таймера, вывести на экран числа массива, содержащие четное количество единиц

06.11.2016, 12:52. Показов 5188. Ответов 11

Студворк — интернет-сервис помощи студентам
Задание: Дан массив A из 10 однобайтовых чисел. Перехватив прерывание от таймера, вывести на экран со сдвигом на один разряд влево только числа, содержащие четное количество единиц.
В качестве образца дали пример обработчика, который выводит секунды на экран. Объясните пожалуйста что и как делать.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
Data segment
    time dw 18          ;переменная таймера 18,2 сигнала в секунду (5 секунд - это 91 прерывания)
    txt  db " ", 13,10,"$"
    cnt  dw 10          ;для счетчика смещения
    trii dw 0
    SAVE_CS DW 0            ;сохраняем сегмент заменяемого прерывания
    SAVE_IP DW 0            ;сохраняем смещение прерывания
Data ends
 
code segment
start: assume cs:code, ds: data, es:stk
    mov AX, data
    mov DS, AX                      ;сохраняем вектор - сохраняем исходные прерывания
    mov AH, 25h         ;функция получения вектора
    mov AL, 8h          ;номер вектора
    int 21h             ;
    mov SAVE_IP, BX         ;запоминаем смещение в BX
    mov SAVE_CS, ES         ;запоминаем сегмент в ES
 
    push DS
    mov DX,offset rout      ;смещение для процедуры в DX
    mov AX, seg rout        ;помещаем сегмент процедуры в DS
    mov DS, AX
    mov AH, 25h         ;в AH-> функцию установки вектора
    mov AL, 8h          ;в AL-> номер вектора
    int 21h             ;т.е. поменяли прерывание
    pop DS
B:
jmp B
 
rout proc far
    push AX             ;сохраняем все измененные регистры
    push DX
    dec time
    cmp time, 0
    jnz nxt
        dec cnt
        mov AX, 18
        mov time, AX
 
        mov AX, trii
        inc BX          ;
        mov CX, 1
        add AX, CX
        jc codeend
        mov trii, AX
        call PrintNumber    ;вызов процедуры вывода на экран числа из AX
        mov AH, 9h
        lea DX, txt     
        int 21h
    nxt: 
    pop DX
    pop AX              ;восстановили регистры
    mov AL, 20h         ;аппаратное прерывание 
    out 20h, AL         ;
    iret
rout endp
 
PrintNumber proc            ;процедура показа числа из AX
    push BX             ;сохраняем содержимое регистров в стек, чтобы потом вернуть их
    push DX
    push SI
    push CX
    mov CX, 0           ;инициализируем цикл
    mov BX, 10          ;в BX заносим основание системы счисления
loophere:               ;основной цикл
    mov DX, 0           ;обнуляем DX
    div BX              ;делим на 10
    
    push AX             ;результат в стеке
    add DL, "0"         ;конвертируем последнюю цифру в ASCII-код
 
    pop AX              ;вернем AX
    push DX             ;сохраним DX
    inc CX              ;увеличим CX на 1
    cmp AX, 0           ;повторяем для всех цифр числа
jnz loophere
    mov AH, 2           ;DOS-функция вывода символа
loophere2:
    pop DX              ;восстанавливаем цифры от последней к первой и 
    mov AH, 02h         ;выводим их на экран
    int 21h
loop loophere2
 
    pop CX
    pop SI
    pop DX
    pop BX
     ret
PrintNumber endp            
 
codeend:                ;восстанавливаем исходный вектор
    CLI
    push DS
    mov DX, SAVE_IP
    mov AX, SAVE_CS
    mov DS, AX
    mov AH, 25h
    mov AL, 1ch
    int 21h
    pop DS
    STI
 
mov AX, 4ch
int 21h
code ends
    
stk segment stack
        db 256 dup ("*")
stk ends
 
end start
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.11.2016, 12:52
Ответы с готовыми решениями:

Перехватив прерывание от таймера, вывести из массива А на экран все числа, большие 05h и меньшие 20h
В общем, есть программа, которая выполняет следущее: Дан массив A из 10 однобайтовых чисел. Перехватив прерывание от таймера, вывести на...

Перехватив прерывание от таймера, вывести на экран последовательность степеней числа 2
Перехватив прерывание от таймера, вывести на экран последовательность степеней числа 2. Вывод прекратить, когда числа выйдут за пределы...

Перехватив прерывание от таймера вывести на экран со сдвигом на один разряд вправо элементы массива
Кто-нибудь знает как решить данную задачу?:( Очень прошу помочь. Дан массив A из 10 однобайтовых чисел. Перехватив прерывание от...

11
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,304
Записей в блоге: 12
06.11.2016, 19:31
Лучший ответ Сообщение было отмечено Киловат как решение

Решение

Строка 14 - не 25h, а 35h (получение вектора).
Строка 32/33 и 52/53 - сохранены не все регистры, лучше заменить на pusha и popa соответственно.

Вместо jmp B (строка 29) лучше написать:
Assembler
1
2
3
4
5
6
7
8
9
10
xor ah,ah
int 16h  ; ждём нажатия клавиши
 
mov ax,2508h
mov ds,SAVE_CS
mov dx,SAVE_IP
int 21h  ; восстанавливаем вектор прерывания таймера
 
mov ax,4C00h
int 21h
Строки 34-51 меняем на проверку цифр и вызов call PrintNumber.
Проверять кол-во единиц в числе (al) можно так:
Assembler
1
2
or al,al
jp Label  ; прыжок, если чётное кол-во единиц (jnp - нечётное)
p.s. Странно, что прога вместо передачи управления "оригинального" обработчику прерывания "разблокирует" (или как там это называется правильно - не помню уже) обработчик прерывания (mov al,20h / out 20h,al).

Вот макет правильной программы для работы с прерываниями (вариант COM-программы):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.MODEL Tiny
.286
.CODE
ORG     100h
 
Start:
 
                jmp     SetIntVec
 
Handler:                               ; Обработчик прерывания
                pusha
; здесь идёт основная работы
                popa
 
RealInt:        db      0EAh           ; Возвращаем управление прерыванию
RealAddr        dw      ?,?
 
TSREnd          =       $
 
;----------------------------------------------------------------------------;
 
SetIntVec:
                mov     ax,3508h
                int     21h
                mov     RealAddr[0],bx
                mov     RealAddr[2],es
                mov     ah,25h
                lea     dx,Handler
                int     21h
 
                mov     ah,9
                lea     dx,Message
                int     21h
 
                mov     ah,49h
                mov     es,ds:[2Ch]
                int     21h
 
                lea     dx,TSREnd
                int     27h
 
END Start
Только здесь прога завершается, оставаясь резидентной.
1
0 / 0 / 0
Регистрация: 02.11.2015
Сообщений: 57
06.11.2016, 20:57  [ТС]
Цитата Сообщение от Jin X Посмотреть сообщение
Строки 34-51 меняем на проверку цифр и вызов call PrintNumber.
Пытался примитивно вывести просто массив, чтобы удостовериться в правильности и получил кашу цифр. Знаю, что очень глупо, но что не так?

Assembler
1
2
3
4
5
6
7
8
  mov si,0 
    mov CX,10   
cicl:
    mov al, A[si]
    call PrintNumber
    inc si
    loop cicl
    ret
Миниатюры
Перехватив прерывание от таймера, вывести на экран числа массива, содержащие четное количество единиц  
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,304
Записей в блоге: 12
06.11.2016, 21:25
Не так то, что нужно нарисовать, например, запятую между выводом каждой цифры. К примеру:
Assembler
1
2
3
mov ah,2
mov dl,','
int 21h
1
0 / 0 / 0
Регистрация: 02.11.2015
Сообщений: 57
06.11.2016, 21:28  [ТС]
Цитата Сообщение от Jin X Посмотреть сообщение
Не так то, что нужно нарисовать, например, запятую между выводом каждой цифры. К примеру:
Вот
Миниатюры
Перехватив прерывание от таймера, вывести на экран числа массива, содержащие четное количество единиц  
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,304
Записей в блоге: 12
06.11.2016, 21:37
Процедура PrintNumber выводит значение из ax, а не из al.
Регистр ah кто очищать будет?
1
0 / 0 / 0
Регистрация: 02.11.2015
Сообщений: 57
06.11.2016, 21:41  [ТС]
Цитата Сообщение от Jin X Посмотреть сообщение
Регистр ah кто очищать будет?
Тогда все верно)
Миниатюры
Перехватив прерывание от таймера, вывести на экран числа массива, содержащие четное количество единиц  
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,304
Записей в блоге: 12
06.11.2016, 22:05
Можно ещё сделать проверку на cx=1, чтобы не выводить лишнюю запятую.
1
0 / 0 / 0
Регистрация: 02.11.2015
Сообщений: 57
06.11.2016, 22:15  [ТС]
Цитата Сообщение от Jin X Посмотреть сообщение
Можно ещё сделать проверку на cx=1, чтобы не выводить лишнюю запятую.
Или просто пробел вместо запятой взять.

Добавлено через 5 минут
Цитата Сообщение от Jin X Посмотреть сообщение
or al,al
jp Labe
По идее так должно выводить числа с четным количеством единиц?

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    mov si,0 
    mov CX,10   
cicl:
    mov al, A[si]
    or al,al
    jp ab
ab:    
    call PrintNumber
    inc si
    mov ah,2
    mov dl,' '
    int 21h
    xor ah,ah
    loop cicl
    ret
    jc codeend
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,304
Записей в блоге: 12
06.11.2016, 22:22
Нет, не так.
Давайте поразмышляем: что будет, если число будет чётным? Произойдёт переход на метку ab. А что будет, если число будет нечётным? Произойдёт переход на следующую команду, а следующая команда какая?

xor ah,ah логичнее поместить перед call

Добавлено через 1 минуту
И строка 16 зачем вообще?
1
0 / 0 / 0
Регистрация: 02.11.2015
Сообщений: 57
06.11.2016, 22:42  [ТС]
Цитата Сообщение от Jin X Посмотреть сообщение
Давайте поразмышляем: что будет, если число будет чётным? Произойдёт переход на метку ab. А что будет, если число будет нечётным? Произойдёт переход на следующую команду, а следующая команда какая?
Так, надо отключить логику двух плюсов на время

Добавлено через 18 минут
Я неожиданно опомнился, прочитав снова задание. "При каждом вызове процедуры обработчика запроса на обслуживание прерывания обрабатывать только один элемент массива". То есть сначала нужно произвести все процедуры по сортировке, результат занести в новый массив как положено, а затем между строками
Assembler
1
2
3
4
5
6
pop DX
    pop AX              ;восстановили регистры
    mov AL, 20h         ;аппартаное прерывание 
    out 20h, AL         ;
    iret
rout endp
3 и 4 запросить вывод массива. Я прав или нет?
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6812 / 2052 / 238
Регистрация: 14.12.2014
Сообщений: 4,304
Записей в блоге: 12
06.11.2016, 23:36
3 и 4 - это посыл команды "конец прерывания" контроллеру прерываний, чтобы прерывание вызвалось в следующий раз (т.к. нет вызова "старого" прерывания). Ничего общего с массивами это не имеет.

Нужно объявить переменную, которая будет хранить позицию текущего числа (то самое значение si).
После каждого прерывания позиция будет увеличиваться на 1 (а может, и больше, если число единиц вдруг попадётся нечётное).
Короче, пишу на ходу, возможны ошибки:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
; в сегменте data
Pos dw offset A
. . .
; начало обработчика прерывания
  pusha
@@next:
  mov bx,[Pos]
  cmp bx,offset Pos+ДлинаМассива
  jae @@exit
  inc [Pos]
  mov al,[bx]
  or al,al
  jnp @@next
  xor ah,ah
  call PrintNumber
  mov ah,2
  mov dl,' '
  int 21h
@@exit:
  ; числа закончились (тут можно восстановить старый обработчик прерывания, если надо)
  mov al,20h
  out 20h,al
  popa
  iret
Добавлено через 2 минуты
Поправил малость...

Добавлено через 2 минуты
Меня ещё смущает выражение "со сдвигом на один разряд влево".
Видимо, вместо пробела надо вывести на экран backspace (mov dl,8) и поместить это перед call PrintNumber'ом.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.11.2016, 23:36
Помогаю со студенческими работами здесь

Перехватив прерывание от таймера, вывести на экран со сдвигом на один разряд вправо элементы массива
Может мне кто-то объяснить или может быть ссылочкой поделиться, что означает "перехват прерывания от таймера?". Задание само...

Перехватив прерывание от таймера вывести на экран сумму двух соседних нечетных элементов массива
Дан массив A из 10 однобайтовых чисел. Перехватив прерывание от таймера вывести на экран сумму двух соседних нечетных элементов массива.

Дан массив A из 10 однобайтовых чисел. Перехватив прерывание от таймера вывести на экран только четные числа
Здравствуйте, есть такой вопрос, который мой мозг не в состоянии разрешить. Как можно исправить код (в файле), чтобы выводились только...

Массив: Вывести на экран со сдвигом на один разряд влево только числа, содержащие четное количество единиц
Нужна помощь! Дан массив Array из 10 однобайтовых чисел. Вывести на экран со сдвигом на один разряд влево только числа, содержащие четное...

Перехватив прерывание от таймера, вывести на экран последовательность квадратов натуральных чисел
Перехватив прерывание от таймера, вывести на экран последовательность квадратов натуральных чисел. Заполнение прекратить, когда...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru