Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Реализовать вызов процедуры через системное прерыв 
:(
    Опции темы
mycodeurnightmare
  Дата 20.9.2015, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 26.10.2014

Репутация: нет
Всего: нет



Доброго времени суток. Вот задание: Реализовать вызов процедуры через системное прерывание для создания нового массива из положительных чисел произвольного массива однобайтных чисел. Входные параметры: адрес исходного массива, его длина, адрес нового массива.
Вот код с процедурой. Но не понимаю теперь как правильно записать адрес собственной процедуры в вектор прерывания. :С Заранее огромное спасибо.
Код

.386
dseg segment use16
mass1 db 1,-20,30,40,-30,50,-40,100,-45,2 
dseg ends
eseg segment use16
mass2 db 10 dup(?)
eseg ends
cseg segment use16
assume ds:dseg, cs:cseg, es:eseg
;загрузка регистров-указателей сегментов ds, es
code:  mov cx, dseg 
       mov ds, cx
       mov cx, eseg
       mov es, cx
;входные параметры процедуры
lea si, ds:mass1
mov cx,10
lea di, es:mass2
call maspr
;завершение исполнения
mov ah, 4ch 
int 21h
;объявление поцедуры
maspr proc
cycl: cmp byte ptr ds:[si], 0
jl m1
movsb
jmp m2
m1:inc si
m2:loop cycl
ret 
maspr endp
cseg ends
end code

PM MAIL   Вверх
ФедосеевПавел
Дата 20.9.2015, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: 4
Всего: 10



К сожалению, у меня уже нет WinXP, где легко работалось с DOS, и нет виртуальной машины с DOS. Поэтому, подскажу "на словах" в общем виде.
1. Почитайте о прерываниях, о перехвате прерываний, восстановлении исходных векторов.
2. Сделайте перехват 21h прерывания по какой-нибудь неиспользуемой функции (html версия DJDeloriae знаменитого InterruptList от Ralf Brown, или другая версия, даже более удобная) - например 74h. В своём обработчике сделайте проверку - если функция 74h, то вызывайте maspr, иначе отдавайте управление старому обработчику.
3. В программе вызывайте вместо maspr прерывание int 21h fn=74h.
4. Перед завершением программы восстанови исходный обработчик.

Чтение вектора прерывания - int 21h fn=35h. Запись вектора прерывания int 21h fn=25h.

Внизу представлены примеры.
Диспетчер в прерывании 21h - не проверял, но как пример подойдёт.
Пример установки новых обработчиков прерываний
Ещё пример
PM MAIL   Вверх
mycodeurnightmare
Дата 20.9.2015, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 26.10.2014

Репутация: нет
Всего: нет



Цитата(ФедосеевПавел @ 20.9.2015,  11:32)
К сожалению, у меня уже нет WinXP, где легко работалось с DOS, и нет виртуальной машины с DOS. Поэтому, подскажу "на словах" в общем виде.
1. Почитайте о прерываниях, о перехвате прерываний, восстановлении исходных векторов.
2. Сделайте перехват 21h прерывания по какой-нибудь неиспользуемой функции (html версия DJDeloriae знаменитого InterruptList от Ralf Brown, или другая версия, даже более удобная) - например 74h. В своём обработчике сделайте проверку - если функция 74h, то вызывайте maspr, иначе отдавайте управление старому обработчику.
3. В программе вызывайте вместо maspr прерывание int 21h fn=74h.
4. Перед завершением программы восстанови исходный обработчик.

Чтение вектора прерывания - int 21h fn=35h. Запись вектора прерывания int 21h fn=25h.

Внизу представлены примеры.
Диспетчер в прерывании 21h - не проверял, но как пример подойдёт.
Пример установки новых обработчиков прерываний
Ещё пример

Спасибо за помощь, но... наверное я что-то совсем не так делаю или не понимаю, как оно работает, ибо резидент не вызывается.  
Код

.386
dseg segment use16
mass1 db 1,-20,30,40,-30,50,-40,100,-45,2
vect dd ?
dseg ends
eseg segment use16
mass2 db 10 dup(?)
eseg ends
cseg segment use16
assume ds:dseg, cs:cseg, es:eseg
;загрузка регистров-указателей сегмента ds
code:  mov cx, dseg 
       mov ds, cx
       mov cx, eseg
       mov es, cx
;сохраним адрес обработчика прерываний
mov ah,35h
mov al,69h
int 21h                
mov word ptr ds:vect,bx     ;Вначале младшее слово (смещение)
mov word ptr ds:vect+2,es ;Затем старшее (сегмент)
push ds

mov cx, cs
mov ds, cx
lea dx,maspr
mov ah,25h
mov al,69h
int 21h
pop ds    

;входные параметры процедуры    
mov cx,10
lea si, ds:mass1
lea di, es:mass2
;вызовем резидентный обработчик прерывания
mov ah, 69h
mov al,0
int 21h
;восстановим старый обработчик прерывания
mov dx,word ptr ds:vect
mov ds, word ptr ds:vect+2
mov ah, 25h
mov al,69h
int 21h
;завершение исполнения
mov ah, 4ch    
int 21h
;объявление поцедуры
maspr proc
cycl: cmp byte ptr ds:[si], 0
jl m1
movsb
jmp m2
m1:inc si
m2:loop cycl
iret    
maspr endp
cseg ends
end code

PM MAIL   Вверх
ФедосеевПавел
Дата 20.9.2015, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: 4
Всего: 10



А это не будет резидентом, просто на время запуска своей программы к некоторым возможностям можно будет обратиться через программное прерывание.

По-моему здесь нужно ASSUME
Код

mov cx, cs
mov ds, cx
assume ds:cseg  <----- или assume ds:nothing
lea dx,maspr   <----- а здесь, может быть mov dx, OFFSET maspr или lea dx, cs:maspr
mov ah,25h
mov al,69h
int 21h
pop ds
assume ds:dseg  <-----

Кроме того, это код установки прерывания int 69h. Пусть будет 69, но тогда в дальнейшем его и нужно вызывать, а не 21h для вызова maspr.

Ещё нужно объявление стека размером хотя бы 1кБайт.

Почитай учебники. Мне сложно давать советы без виртуальной машины с DOS.
PM MAIL   Вверх
mycodeurnightmare
Дата 20.9.2015, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 26.10.2014

Репутация: нет
Всего: нет



Спааасибо Вам огромное, всё заработало.  smile 
Код

.386
dseg segment use16
mass1 db 1,-20,30,40,-30,50,-40,100,-45,2
vect dd ?
dseg ends
eseg segment use16
mass2 db 10 dup(?)
eseg ends
cseg segment use16
assume ds:dseg, cs:cseg, es:eseg

;загрузка регистров-указателей сегмента ds
code:  mov cx, dseg 
       mov ds, cx
       mov cx, eseg
       mov es, cx

;сохраним адрес обработчика прерываний
push es
mov ah,35h
mov al,69h
int 21h                
mov word ptr ds:vect,bx     ;Вначале младшее слово (смещение)
mov word ptr ds:vect+2,es ;Затем старшее (сегмент)
pop es
push ds

;изменение вектора
mov cx, cs
mov ds, cx
lea dx, cs:maspr
mov ah,25h
mov al,69h
int 21h
pop ds    

;входные параметры процедуры    
mov cx,10
lea si, ds:mass1
lea di, es:mass2
;вызовем резидентный обработчик прерывания
int 69h

;восстановим старый обработчик прерывания
mov dx,word ptr ds:vect
mov ds, word ptr ds:vect+2
mov ah, 25h
mov al,69h
int 21h

;завершение исполнения
mov ah, 4ch    
int 21h

;объявление поцедуры
maspr proc
cycl: cmp byte ptr ds:[si], 0
jl m1
movsb
jmp m2
m1:inc si
m2:loop cycl
iret    
maspr endp
cseg ends
end code


Это сообщение отредактировал(а) mycodeurnightmare - 20.9.2015, 17:04
PM MAIL   Вверх
R71MT
Дата 20.9.2015, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 28.7.2015

Репутация: нет
Всего: 1



...процедуры не интересны! Интересно, что вектор потом восстановил! 

Это сообщение отредактировал(а) R71MT - 25.9.2015, 20:36
PM MAIL   Вверх
R71MT
Дата 25.9.2015, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 28.7.2015

Репутация: нет
Всего: 1



Можно просто проверить старшую единицу каждого элемента..
На FASM'e это выглядит так (без сохранения/востановления вектора):
Код

USE16
ORG 100h
JMP start

hello   DB   'НАЙДЕНО ЭЛЕМЕНТОВ: $'
mass1   DB   1,-20,30,40,-30,-50,40,100,-45,2
leght   DB   0                   ; счётчик найденных элементов

start:
  PUSH  DS
  MOV   AX,2580h                 ; свой обработчик на INT-80h
  MOV   DX,new_80
  INT   21h
  POP   DS

  MOV   SI,mass1                 ; SI = адрес массива
  MOV   CX,10                    ; CX = его длинна
  INT   80h         ;<===========; зовём свой обработчик! =========================//

  MOV   AH,9                     ; выводим мессагу юзеру
  MOV   DX,hello
  INT   21h

  MOV   AL,[leght]               ; AL = счётчик положительных элементов массива
  ADD   AL,30h                   ; переводим значение в ASCII-символ
  INT   29h                      ; выводим его на экран

  XOR   AX,AX                    ; ждём клавишу..
  INT   16h
  RET                            ; ..и на выход!

;//============ ОБРАБОТЧИК INT-80h ================================================//
new_80:
  LODSB                          ; берём символ из DS:SI
  TEST  AL,80h                   ; проверяем старшую единицу (80h = 1000 0000b)
  JZ    next                     ; если нуль - число положительное!
  LOOP  new_80                   ; значит единица. Берём следующий символ массива
next:
  INC   BYTE[leght]              ; увеличиваем счётчик,
  LOOP  new_80                   ;        ..и мотаем цикл CX-раз.
  IRET                           ; возвращаем управление программе

PM MAIL   Вверх
Google
  Дата 23.10.2019, 17:00 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.1285 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.