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

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

08.12.2019, 17:20. Показов 4405. Ответов 6

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

При запуске возникают данные ошибки:

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
code segment
assume CS:code,DS:data
main proc
mov AX,data ; Инициализация сегментного
mov DS,AX ; регистра DS
;Сохраним исходный вектор
mov AH,35h ; Функция получения вектора
mov AL,08h ; Номер вектора
int 21h
mov word ptr old_08,BX ; Смещение исходного обработчика
mov word ptr old_08+2,ES ; Сегмент исходного обработчика
;Установим наш обработчик
mov AH,25h ;Функция заполнения вектора
mov AL,08h ; Номер вектора
mov DX,offset my_08 ; Смещение нашего обработчика
push DS ; Сохраним DS=data
push CS ; Перепишем CS в DS
pop DS ; через стек. DS:DX->new_08
int 21h
pop DS ; Восстановим DS=data/Перед завершением программы восстановим исходный вектор
Lds DX ,old_08 ; Заполним DS:DX из old_08
mov AH,25h ; Функция заполнения вектора
mov AL,08h ; Номер вектора
int 21h
mov AX,4C00h ;Функция завершения программы
int 21h
main endp
;Процедура обработчика прерываний от таймера
my_08 proc
push AX ;Сохраним исходное значение AX
mov ax,2
a1: mul 2
JC a2
push ax ;Cохраним число
push -1 ;Сохраним признак конца числа
mov cx,10 ;Делим на 10
l: mov dx,0 ;Очистим регистр dx (xor dx,dx - оптимальнее)
div cx ;Делим
push dx ;Сохраним цифру
cmp ax,0 ;Остался 0? (оптимальнее or ax,ax)
jne l ;нет -> продолжим
mov ah,2h
l2: pop dx ;Восстановим цифру
cmp dx,-1 ;Дошли до конца -> выход {оптимальнее: or dx,dx jl ex}
je ex
add dl,'0' ;Преобразуем число в цифру
int 21h ;Выведем цифру на экран
jmp l2 ;И продолжим
ex: mov ax,4c00h ;Выход
int 21h
 
pop ax ;Восстановим число
Loop a1
a2: mov AL,20h ;Разблокировка прерываний
out 20h,AL ;в контроллере прерываний
pop AX ;Восстановим AX
iret ;Возврат в прерванную программу
my_08 endp
code ends
data segment
old_08 db 0 ;Ячейка для хранения исходного вектора
data ends
stk segment stack
db 256 dup(0)
stk ends
end main
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.12.2019, 17:20
Ответы с готовыми решениями:

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

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

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

6
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8658 / 4494 / 1669
Регистрация: 01.02.2015
Сообщений: 13,904
Записей в блоге: 12
08.12.2019, 18:05
Размер переменной другой
Assembler
61
old_08 dd 0 ;Ячейка для хранения исходного вектора
На число умножать нельзя - не поддерживается такой формат
Assembler
32
a1: mul 2
Используйте сдвиг влево shl

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

Ещё раз повторю: Если все 16 чисел вывести за 1 вызов прерывания таймера - отработайте без таймера.
0
Модератор
1245 / 676 / 292
Регистрация: 10.11.2019
Сообщений: 1,406
09.12.2019, 18:30
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
; В Windows XP стабильно идёт в эмуляторе DosBox
; и не очень хорошо в консоли XP (экран не очищается при CLS)
    .286
    .model small
    .code
start:  jmp beg
; вектор старого прерывания
old8int label dword
old8ip  dw  0
old8cs  dw  0
; адрес видеопамяти символа
vaddr   dw  0
; позиция курсора
x   db  0
y   db  0
; степени 2
power2  dw  1
; счётчик прерываний
intcnt  db  0
; видео атрибут символа (белый на синем)
attrib  db  16*1+15
beg:    push cs
    pop  ds
    cld
    call cls ; выводится "Hel" чтобы проверить 
    mov al,"H" ; работает ли программа вообще
    call putchar
    mov al,"e"
    call putchar
    mov al,"l"
    call putchar
    mov x,0   ; курсор в позицию 1,0
    mov y,1
    call at
    mov ax,3508h ; получаем вектор старого прерывания
    int 21h
    mov old8ip,bx
    mov old8cs,es
    mov dx,offset new8int ; устанавливаем новый вектор
    push cs
    pop  ds
    mov ax,2508h ; set new interrupt
    int 21h
wt: cmp intcnt,16 ; дождаться пока пройдёт 16 прерываний
    jnz wt
    lds dx,old8int ; DS:DX=старый вектор прерывания
    mov ax,2508h ; set old interrupt
    int 21h
    mov x,0   ; курсор в позицию 20,0
    mov y,20
    call at
    mov ax,4C00h ; выход в DOS
    int 21h
 
new8int:pushf ; вызываем старое прерывание
    call old8int
    push ds ; важно - сохраняем все регистры, иначе система рухнет
    push es
    pusha
    call intcall ; вызываем нашу подпрограмму обработки
    popa    ; восстанавливаем регистры
    pop  es
    pop  ds
    iret
 
intcall:cmp intcnt,16 ; если счётчик достиг 16, ничего не делать
    jnc ic1
        mov x,0 ; установить курсор
        call at
    mov  ax,power2 ; вывести значение power2
    call printdigit
    mov  ax,power2 ; power2=power2*2
    add  ax,ax
    mov power2,ax
    inc y  ; увеличить номер строки
    inc intcnt ; увеличить счётчик прерываний
ic1:    ret
 
printdigit: ; вывод слова AX в десятичном виде
    push ax
    push bx
    push cx
    push dx
    mov cx,0
nextdig:mov dx,0
    mov bx,10
    div bx
    push dx
    inc  cx
    cmp ax,0
    jnz nextdig
    jcxz m1
m0: pop  ax
    add  al,"0"
    call putchar
    loop m0
m1:     pop  dx
    pop  cx 
    pop  bx
    pop  ax
    ret
 
cls:    push es ; очистить экран цветом attrib
    push ax
    push cx
    push di
    mov  di,0B800h ; сегмент видеопамяти DOS
    mov es,di
    mov di,0
    mov cx,80*25  ; размер текстового экрана
    mov al,20h
    mov ah,attrib
    rep stosw     ; собственно стирание
    mov x,0       ; курсор в позицию 0,0
    mov y,0
    call at
    pop  di
    pop  cx
    pop  ax
    pop  es
    ret
 
at: push ax ; установка курсора
    push bx
    push dx
    mov  al,y ; vaddr=(80*y+x)*2
    mov ah,80
    mul ah
    mov bl,x
    mov bh,0
    add ax,bx
    add ax,ax
    mov vaddr,ax
    mov bh,0 ; bios set cursor
        mov dh,y
    mov dl,x
    mov ah,2
    int 10h
    pop dx
    pop bx
    pop ax
    ret
 
putchar:push es ; вывод символа AL цветом attrib на экран
    push ax
    push di
    mov  di,0B800h
    mov es,di
    mov di,vaddr
    mov ah,attrib
    stosw ; собственно вывод
    mov vaddr,di
    pop  di
    pop  ax
    pop  es
    ret
        
    end start
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8658 / 4494 / 1669
Регистрация: 01.02.2015
Сообщений: 13,904
Записей в блоге: 12
09.12.2019, 19:51
Это победа?
0
Модератор
1245 / 676 / 292
Регистрация: 10.11.2019
Сообщений: 1,406
09.12.2019, 20:21
Вообще дальше можно исправлять:

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
cls:    push ax ; очистить экран цветом attrib
    push bx
    push cx
    push dx
    mov  cx,0 ; верхний левый угол
    mov  dx,24*256+79 ; нижний правый угол
    mov  bh,attrib
    mov  ax,0600h ; стереть прямоугольник
    int  10h
    mov x,0       ; курсор в позицию 0,0
    mov y,0
    call at
    pop  dx
    pop  cx
    pop  bx
    pop  ax
    ret
 
 
putchar: push ax
    mov ah,0Eh
    int 10h
    pop ax  
    ret
Так вроде бы и короче, и работает стабильней
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8658 / 4494 / 1669
Регистрация: 01.02.2015
Сообщений: 13,904
Записей в блоге: 12
09.12.2019, 20:31
qbfan, я почему-то решил, что вы топикстартер.
Раз приводите решение, то хотя бы вкратце расскажите о нём. Непонятно, чем оно лучше предложенного топикстартером.
0
Модератор
1245 / 676 / 292
Регистрация: 10.11.2019
Сообщений: 1,406
10.12.2019, 13:48
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Когда-то давным-давно, в конце 80х годов
все компьютерные журналы были забиты программами-русификаторами
дисплея и клавиатуры, из которых можно было понять, как организовать
работу по прерываниям и резидентные программы. Сейчас эта информация
просто забыта и утеряна. Также есть небольшой секрет - очень старая
программа под DOS - Tech Help by Dan Rollings, из которой можно
почерпнуть практически всю информацию о компьютерах 90х годов
(функции DOS, BIOS, порты ввода-вывода, система команд 286 процессора)
Очень рекомендую скачать эту программу из Сети.
Основная идея аппаратного прерывания - это некая подпрограмма, которая
получает управление под действием контроллера прерываний и выполняет
некие действия, не нарушая при этом работу основной программы
(например текстового редактора или игры, запущенной в данный момент)
Есть ещё прерывания 0 - деление на ноль, 1 - пошаговая отладка,
но речь пока не о них. Важно понять, что в современных компьютерах
прямое перепрограммирование контроллера прерываний (как это было в DOS)
недопустимо, так как нарушит работу Windows. Очень хорошо, что
у Kuabi не дошло дело до реального запуска собственной программы
так как внутри прерывания используются функции DOS Int 21h и особенно
выход в DOS по AX=4C00h. Это неизбежно привело бы к краху системы.
Внутри аппаратных прерываний крайне нежелательно использовать функции
DOS, для этого используются специальные трюки. Но нам это и не нужно -
мы можем воспользоваться функциями BIOS для работы с дисплеем Int 10h
или даже прямым обращением к видеопамяти через сегмент 0B800h.
Но важно понять, что работа DOS программ в Windows эмулируется,
например мы заносим в 0B800h:0000h слово 0721h (восклицательный знак),
а Windows опять-таки через достаточно сложный и запутанный механизм
прерываний рисует "!" (по точкам) в режиме True Color в окне консоли,
причём мы можем двигать окно мышкой и даже запускать одновременно
несколько одинаковых программ в разных окнах, и все они должны
выполняться без ошибок.

Итак, мы используем внутри нашего прерывания по тайьеру Int 10,
а также вызываем старую функцию прерывания (которая выдает
аппаратное подтверждение mov AL,20h mov 20h,AL так что эти две
команды мы уже не пишем). Ключевой для понимания является команда

Assembler
1
2
wt: cmp intcnt,16
    jnz wt
На первый взгляд ничего не происходит, и программа должна
зависнуть. На самом деле выполняется наше прерывание, которое меняет
intcnt. Далее всё просто: printdigit печатает на дисплее число,
cls стирает экран указанным цветом, at устанавливает курсор
(если не нравится название, можно поменять например на locate)
putchar выводит на экран символ.

Компилировалось на MASM 5.10 и TASM 4.0
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.12.2019, 13:48
Помогаю со студенческими работами здесь

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

Вывести на экран таблицу степеней числа 2
Вывести на экран таблицу степеней числа 2 (от нулевой до двадцатой) в два столбца. Дан одномерный массив размерностью 8, заполненный...

Вывести на экран таблицу степеней числа 5 (от нулевой до 12-й)
Пользователь вводит целое положительное число m. Найти наименьшее натуральное число k, при котором 5(в степ)k > m. Вывести на экран...

Вывести на экран таблицу степеней числа 5 от нулевой до n-ой
Написать программу, выводящую на экран таблицу степеней числа 5 от нулевой до n-ой. .

Вывести на экран таблицу степеней для произвольного числа
Составить программу, которая выводит на экран таблицу степеней для произвольного числа! помогите составить!!!!


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
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 с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru