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

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

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.12.2010, 16:28   #1
sirka
 
Регистрация: 23.12.2010
Сообщений: 7
По умолчанию Таблица векторов прерываний

Мне нужно вывести таблицу векторов прерываний на экран.
Обращаюсь к вектору функцией 35h (mov ah,35h) и номером вектора al (mov al,1 например)
Вектора считываю и заношу просто в хранилище. Но при выводе на экран, шестнадцатеричный код вектора воспринимается как 4 символа (то есть по 2 цифры на символ). А мне нужно вывести просто код этих символов , а не их самих. В общем вот прога моя. Помогите люди, прошу очень. Курсач как-никак =).
Код:
text segment
assume CS:text,DS:data
begin:
mov ax,data
mov ds,ax
mov cx,25
mov al,0 ;обнуляю номер вектора
go1:
mov ah,35h ;вызываю функцию чтения вектора
add al,1 ;прибавляю к номеру 1, то есть просто последовательно буду их читать
int 21h ; тут у нас уже в ES:[BX] лежит адрес вектора
push ax

mov word ptr buf, bx ;заношу вектор в хранилище
mov word ptr buf+2, es


push cx
mov ah,40h
mov bx,1
mov cx, ole
mov dx, offset buf ;делаю вывод на экран
int 21h
pop cx
pop ax
loop go1
mov ah,4Ch
mov al,1
int 21h
text ends
data segment
buf db 64 dup (?),13,10
ole=$-buf
data ends
stk segment stack
db 256 dup (0)
stk ends
end begin
Можете написать свою прогу, не возражаю. Просто вывести IVT на экран. Заранее спасибо )

Последний раз редактировалось Stilet; 23.12.2010 в 16:42.
sirka вне форума Ответить с цитированием
Старый 23.12.2010, 18:51   #2
Ant1971on
Пользователь
 
Регистрация: 20.07.2010
Сообщений: 52
По умолчанию

Насколько я понял, надо номер вектора, который лежит в буфере в двоичном виде, преобразовать в 16-ричные символы и вывести эти символы на экран. Вот две процедуры, которые как раз это и делают с одним байтом (подсмотрел у П.Нортона ):

Код:
;-----------------------WRITE_HEX----------------------------------------------

;Процедура преобразует байт в регистре DL в шестн.форму
;Используется: WRITE_HEX_DIGIT

WRITE_HEX	PROC NEAR
		PUSH CX			;сохранить знач.используемых регистров
		PUSH DX
		MOV DH,DL		;сохраним копию байта в DH
		MOV CX,4
		SHR DL,CL		;взять старшие 4 бита в DL
		CALL WRITE_HEX_DIGIT	;запись первой 16-ричной цифры
		MOV DL,DH
		AND DL,0FH		;взять мл. 4 бита в DL
		CALL WRITE_HEX_DIGIT	;запись второй 16-ричной цифры
		POP DX                  ;восстановить используемые регистры
		POP CX
		RET
WRITE_HEX	ENDP

;-----------------------WRITE_HEX_DIGIT----------------------------------------

;Процедура преобразует 4 мл.бита в DL в 16-ричн.цифру и выводит ее на экран.
;Используется: WRITE_CHAR

WRITE_HEX_DIGIT	PROC NEAR
		PUSH DX
		CMP DL,10
		JAE HEX_LETTER		;значение в DL>=10 -> буква
		ADD DL,"0"		;значение в DL<10 -> цифра, добавим 30h
		JMP SHORT WRITE_DIGIT	;записать полученный символ
	HEX_LETTER:
		ADD DL,"A"-10		;преобразовать в букву
	WRITE_DIGIT:
		CALL WRITE_CHAR		;вывести символ на экран
		POP DX			;восстановить DX
		RET
WRITE_HEX_DIGIT ENDP
Ant1971on вне форума Ответить с цитированием
Старый 23.12.2010, 20:01   #3
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

И нулевой вектор пропускается, это так задумано? )
Son Of Pain вне форума Ответить с цитированием
Старый 25.12.2010, 06:51   #4
sirka
 
Регистрация: 23.12.2010
Сообщений: 7
По умолчанию

хм... Ну насколько я понял и литературы, то вектор с номером 1 лежит по адресу 0000:0000h . А в al должны заноситься номера, на счет 0 вектора не знаю. Поправьте, если ошибаюсь.
Да спасибо Ant1971on, сейчас попробую =)

Ant1971on, на сколько я понял в процедуре WRITE_CHAR выводить нужно DL ?? то есть просто так же через mov ah,40h вывести , и получу само DL, будь там буквы или цифры (то есть всякие палочки и смайлики уже выводить на экран не будет) ?

Последний раз редактировалось Stilet; 25.12.2010 в 11:46.
sirka вне форума Ответить с цитированием
Старый 25.12.2010, 11:25   #5
Ant1971on
Пользователь
 
Регистрация: 20.07.2010
Сообщений: 52
По умолчанию

Цитата:
на сколько я понял в процедуре WRITE_CHAR выводить нужно DL ??
Именно так.

Цитата:
то есть просто так же через mov ah,40h вывести , и получу само DL, будь там буквы или цифры (то есть всякие палочки и смайлики уже выводить на экран не будет) ?
Через 40h сложнее, придется сначала каждый преобразованный байт из DL отправлять в буфер, который потом и выводить. Наверное лучше использовать 02h (DOS-функция вывода символа на экран, аргумент как раз должен быть в DL ) и выводить каждый вектор (4 байта) побайтово в цикле. Один вектор вывели, переводим строку, выводим следующий и т.д. до конца. Удачи!
Ant1971on вне форума Ответить с цитированием
Старый 25.12.2010, 13:18   #6
sirka
 
Регистрация: 23.12.2010
Сообщений: 7
По умолчанию

Большое спасибо Ant1971on ! =)
sirka вне форума Ответить с цитированием
Старый 25.12.2010, 17:05   #7
Ant1971on
Пользователь
 
Регистрация: 20.07.2010
Сообщений: 52
По умолчанию

Да, совсем забыл... Содержимое вектора, например, ES:BX = 00A7 1068 в буфере будет храниться как 68,10,A7,00. Так что выводить его надо задом наперед, а то получится ерунда. Ну это так, на всякий случай
Ant1971on вне форума Ответить с цитированием
Старый 29.12.2010, 16:40   #8
sirka
 
Регистрация: 23.12.2010
Сообщений: 7
По умолчанию

Хех! блин )) спасиб, совсем забыл , думаю .. что же он мне выводит ))
Хорошо, когда знаешь ассемблер. Очень хорошо ))

Выводит не то, что лежит в DL , подскажите почему?
При вызове функции 02h в DL лежи то, что нужно, а выводит не то. МБ флаги??
Код:
text segment
assume CS:text,DS:data
begin:
      mov ax,data
      mov ds,ax
      mov al,0

      mov ah,35h
      add al,1h
      int 21h

      mov dx,es
      PUSH BX
      mov bx,0000h
      ;PUSH DX

;;;;;;;;;;;;;;;;;;;;;;CTAPLLIuu PA3P9g DL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

WRITE_HEX_DL_ST	PROC NEAR
                ;PUSHF
                ADD BX,1
		MOV DH,DL		;сохраним копию байта в DH
		MOV CX,4
                SHR DL,CL		;взять старшие 4 бита в DL
		CALL WRITE_HEX_DIGIT	;запись первой 16-ричной цифры
                                      ;восстановить используемые регистры
WRITE_HEX_DL_ST	ENDP

;;;;;;;;;;;;;;;;;;;;;;MJIAgLLIuu PA3P9g DL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

WRITE_HEX_DL_ML PROC NEAR
                ;PUSHF
                ADD BX,1
                MOV DL,DH
		AND DL,0FH
               	;взять мл. 4 бита в DL
		CALL WRITE_HEX_DIGIT
                    ;запись второй 16-ричной цифры
WRITE_HEX_DL_ML ENDP

;;;;;;;;;;;;;;;;;;;;;;CTAPLLIuu PA3P9g DH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

WRITE_HEX_DH_ST	PROC NEAR
                ;PUSHF
                ADD BX,1
                MOV DX,ES
		MOV DL,DH		;сохраним копию байта в DH
		MOV CX,4
                SHR DL,CL		;взять старшие 4 бита в DL
		CALL WRITE_HEX_DIGIT	;запись первой 16-ричной цифры
		                     ;восстановить используемые регистры
WRITE_HEX_DH_ST	ENDP

;;;;;;;;;;;;;;;;;;;;;;MJIAgLLIuu PA3P9g DH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

WRITE_HEX_DH_ML PROC NEAR
                ;PUSHF
                INC BX
                MOV DL,DH
		AND DL,0FH
                	;взять мл. 4 бита в DL
		CALL WRITE_HEX_DIGIT
                	;запись второй 16-ричной цифры
WRITE_HEX_DH_ML ENDP

;;;;;;;;;;;;;;;;;;;;;;;;OnpegeJIeHue cuMBoJIa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

WRITE_HEX_DIGIT	PROC NEAR
                ;PUSHF
                CMP DL,10h
		JAE HEX_LETTER		;значение в DL>=10 -> буква
		ADD DL,30h	;значение в DL<10 -> цифра, добавим 30h
		JMP SHORT WRITE_DIGIT	;записать полученный символ
	HEX_LETTER:

                ADD DL,"A"-10
                              ;преобразовать в букву
	WRITE_DIGIT:
		CALL WRITE_CHAR		;вывести символ на экран
		;RET	;восстановить DX
WRITE_HEX_DIGIT ENDP

WRITE_CHAR      PROC

                mov ah,02h
                int 21h
WRITE_CHAR      ENDP
                cmp bl,1
                je WRITE_HEX_DL_ML
                cmp bl,2
                je WRITE_HEX_DH_ST
                cmp bl,3
                je WRITE_HEX_DH_ML

      mov ah,4Ch
      int 21h
text ends

data segment
buf db 32 dup (?),13,10
data ends
stk segment stack
db 256 dup (0)
stk ends
end begin
Помогите пожалуйста =)

Последний раз редактировалось Stilet; 06.01.2011 в 15:37.
sirka вне форума Ответить с цитированием
Старый 07.01.2011, 02:13   #9
Ant1971on
Пользователь
 
Регистрация: 20.07.2010
Сообщений: 52
По умолчанию

Привет ! Вот, написал твою программку, но тоже столкнулся с проблемой. Программа хорошо работает в отладчике, правильно выводит символы, но если запускаю сам экзешник, работает некорректно, то есть где-то выводит верно содержимое вектора, а где-то нет. Почему так происходит - непонятно(я ведь тоже новичок, хоть ты и записал меня в знатоки ассемблера ). Остается ждать помощи более опытных форумчан, может кто-нибудь и подскажет, в чем ошибка.

Код:
CODE_SEG SEGMENT

ASSUME CS:CODE_SEG,DS:DATA_SEG

BEGIN:

	MOV AX,DATA_SEG
	MOV DS,AX

	MOV CX,25
	MOV AL,0

	MOV AH,35h

GET_VCTR:

	INT 21h
	INC AL

;Запомним содержимое вектора в буфере			
	
	MOV WORD PTR BUF,BX     
	MOV WORD PTR BUF+2,ES

;Вывод содержимого вектора на экран:

	MOV SI,3		

PRINT_BYTE:

	MOV DL,BUF[SI]		;отправим преобразуемый байт в DL
	CALL WRITE_HEX		;преобразование байта в символ и вывод на экр.
	DEC SI			;SI -> след.байт
	JNS PRINT_BYTE		;вывод след. байта

;Перевод строки:

	MOV DL,0Dh
	CALL WRITE_CHAR
	MOV DL,0Ah
	CALL WRITE_CHAR

	LOOP GET_VCTR		;считать содерж. след.вектора
	
	MOV AX,4C00h
	INT 21h

;-------------------------Используемые процедуры:-------------------------------

WRITE_HEX PROC
	
	PUSH CX
	PUSH DX
	MOV DH,DL
	MOV CX,4
	SHR DL,CL
	CALL WRITE_HEX_DIGIT
	MOV DL,DH
	AND DL,0Fh
	CALL WRITE_HEX_DIGIT
	POP DX
	POP CX
	RET

WRITE_HEX ENDP

WRITE_HEX_DIGIT PROC

	PUSH DX
	CMP DL,10
	JAE HEX_LETTER
	ADD DL,"0"
	JMP SHORT WRITE_DIGIT
	
HEX_LETTER:

	ADD DL,"A"-10

WRITE_DIGIT:

	CALL WRITE_CHAR
	POP DX
	RET

WRITE_HEX_DIGIT ENDP	
	
WRITE_CHAR PROC

	PUSH AX
	MOV AH,02h
	INT 21h
	POP AX
	RET

WRITE_CHAR ENDP

CODE_SEG ENDS

;------------------------------------------------------------------------------

DATA_SEG SEGMENT

BUF DB 4 DUP (?)

DATA_SEG ENDS

;------------------------------------------------------------------------------

STACK_SEG SEGMENT STACK

DB 256 DUP (0)

STACK_SEG ENDS

END BEGIN
Ant1971on вне форума Ответить с цитированием
Старый 07.01.2011, 06:56   #10
sirka
 
Регистрация: 23.12.2010
Сообщений: 7
По умолчанию

Ну будем думать, соображать. Интересно, если написать в СОМ программе, что-нибудь изменится?
sirka вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Связный список векторов Kekcuk Общие вопросы C/C++ 0 13.12.2010 21:00
Перемножение векторов Smile_Eminsa Общие вопросы C/C++ 0 11.05.2010 09:14
Массив из 2 векторов GreatMuse Общие вопросы C/C++ 6 30.01.2010 22:09
Ввод векторов и матриц, умножение матрицы на вектор и вычисление скалярного призведения двух векторов zverushka Помощь студентам 18 20.02.2009 15:25