Здраствуйте! У меня проблемка, с помощью ф-ии 35h сохранил сегмент и сдвиг вектора прерываний, теперь не могу их выести... Вывожу с помощью ф-ии 40h, пишет что то не то... может я в чем ошибся... Вот код программы -> Код (Text): MASM ;режим работы TASM: ideal или masm MODEL huge ;модель памяти .386 .DATA ;сегмент данных keep_cs dw 0 ;хранит сегмент заменяемого прерывания ; keep_ip dw 0 ;хранит смещение прерывания ; .CODE ;сегмент кода MAIN PROC ; MOV AX,@DATA MOV DS,AX mov ah,35h ;функция получения вектора mov al,21h ;номер вектора int 21h ;теперь сегмент в ES, смещение в BX ;mov keep_ip,bx ;запоминаем смещение mov keep_cs,bx ;запоминаем сегмент ; MOV AH,40H ;номер функции MOV BX,1 ;дескриптор дисплея LEA DX,keep_cs ;загржаем адрес строки MOV CX,16 ;число выводимых байтов INT 21H ; ;MOV AH,09H ;MOV DX,BX ;INT 21H ; MOV AH,4CH ;пересылка 4ch в регистр ah INT 21H ;вызов прерывания с номером 21h MAIN ENDP ;конец процедуры main END MAIN ;конец программы с точкой входа main
Dimka Сдвиг -- это команда такая. А у адресов -- смещения, а не сдвиги. Код (Text): mov ah,35h ;функция получения вектора mov al,21h ;номер вектора int 21h ;теперь сегмент в ES, смещение в BX ;mov keep_ip,bx ;запоминаем смещение mov keep_cs,bx ;запоминаем сегмент Вообще-то, судя по коду, смещение запоминается на месте сегмента, а сегмент вовсе не запоминается. Код (Text): MOV AH,40H ;номер функции MOV BX,1 ;дескриптор дисплея LEA DX,keep_cs ;загржаем адрес строки MOV CX,16 ;число выводимых байтов INT 21H ; Если честно, не помню, что делает фунция 40h прерывания 21h, но почему-то у меня есть смутное ощущение, что она не предназначена для корректного отображения двоичных чисел...
INT 21 - DOS 2+ - WRITE TO FILE WITH HANDLE AH = 40h BX = file handle CX = number of bytes to write DSX -> buffer Return: CF set on error AX = error code CF clear if successful AX = number of bytes written Note: if CX is zero, no data is written, and the file is truncated or extended to the current position
doctor_Ice Спасибо. Собсно, это и ожидал, но уверен не был (список интов у меня обрезанный -- только БИОС, поскольку для ДОСа всё равно не пишу). Dimka В общем, белиберду и должны получить: и сам вектор должным образом не сохраняете, и в читабельный вид его не преобразуете.
Код (Text): mov ah,35h ;функция получения вектора mov al,21h ;номер вектора int 21h ;теперь сегмент в ES, смещение в BX ;mov keep_ip,bx ;запоминаем смещение mov keep_cs,es ;пробовал и с es; запоминаем сегмент тогда вопрос, как правильно его преобразовать и вывести на экран... П.С. просто только начал изучать ассемблер, поэтому могу писать кое что не совсем понимая(((
Dimka Надо сначала из внутреннего (двоичного) вида преобразовать, например, в шестнадцатеричный. И печатать уже шестнадцатеричные числа. Алгоритм перевода сами придумаете, или как?
Dimka Вот подпрограммка, которая вроде как должна преобразовывать число в AX в строку (адрес строки -- в ESI). Указывается заодно число цифр, которые нужно получить (вдруг надо младший байт AX, а не весь регистр) Код (Text): ; Convert value in AX to hexadecimal string ; On enter: ; ax = value ; cx = count of hex dights ; es:di = address of string ; All registers and flags will be saved CvtToHex PROC NEAR pushf pusha mov bx, offset CvtTable std add di, cx dec di @@: push ax and al, 0Fh xlat stosb pop ax shr ax, 4 loop @B popa popf retn CvtToHex ENDP CvtTable DB '0123456789ABCDEF'
Код (Text): @@: push ax and al, 0Fh xlat stosb pop ax shr ax, 4 loop @B вот тут вопрос, что значит @@: push ax
Dimka @@ это безымянная метка. чтобы на нее сослаться можно использовать @B или @F @B ссылается на ближайшую предыдущую безымянную метку (Backward) @F ссылается на следующую ближайшую безымянную метку (Forward) используется типа такого: ; some loop @@: .... loop @B или test eax, eax jz @F ... @@:
Код (Text): ; MASM ;режим работы TASM: ideal или masm ; MODEL SMALL ;модель памяти ; .386 ; .DATA ;сегмент данных CvtTable DB '0123456789ABCDEF' ; .CODE ;сегмент кода ; MAIN PROC MOV AX,@DATA MOV DS,AX ; MOV AH,35H ;функция получения вектора MOV AL,21H ;номер вектора 21H INT 21H ;теперь сегмент в ES, смещение в BX mov ax,offset bx call CvtToHex ; MOV AH,40H ;номер функции вывода строки MOV DX,OFFSET di ;загржаем адрес строки MOV BX,1 ;дескриптор дисплея MOV CX,4 ;число выводимых байтов INT 21H ; MOV AH,4CH ;пересылка 4ch в регистр ah INT 21H ;вызов прерывания с номером 21h ; MAIN ENDP ;конец процедуры main ; CvtToHex PROC NEAR pushf pusha mov bx, offset CvtTable std add di, cx dec di @@: push ax and al, 0Fh xlat stosb pop ax shr ax, 4 loop @B popa popf retn CvtToHex ENDP END MAIN ;конец программы с точкой входа main ааа, мазги взрываются!!! что не правильно подскажите плз. при создании .obj пишет следующее-> C:\DOCUME~1\9335~1>C:\TASM\BIN\TASM.EXE a.asm Turbo Assembler Version 4.1 Copyright (c) 1988, 1996 Borland International Assembling file: a.asm **Error** a.asm(52) Undefined symbol: @B Error messages: 1 Warning messages: None Passes: 1 Remaining memory: 452k ====================== но чувствую что еще где то косяк(((
Dimka @@, @B и @F -- это фичи MASM. Попробуйте заменить их на какое-нить другое имя (одинаковое и в метке, и в команде перехода на неё). Или просто вместо @B поставить @@. Похоже, МАСМ и ТАСМ не полностью совместимы
Great С фасмом не знаком Но в данном случае моя подпрограммка была на МАСМе написана, а человек ТАСМ юзает. Вот и выползла несовместимость. Давным-давно тоже ТАСМ юзал, но его ж не развивают
Freeman Угу, на сей ляпсус я внимания не обратил -- заметил только возмущение компилятора по поводу метки
Все, стал более менее жогонять, и нашел процедуру для 10х, переделал под 16чные, вобщем вод код программы, авось каму пригодиться (правда немного не доделан, ща ищу как вводить 16чные символы с клавы=)) Код (Text): MODEL SMALL ;модель памяти .386 .DATA ;сегмент данных tbl DB '0123456789ABCDEF' ;таблица res db 2 dup(' ') ;результат db '$' del db 16 text db 'Vv Prerivanie','$' .CODE ;сегмент кода start: mov ax,@DATA mov ds,ax mov ah,02h ;ввод с клавиатуры int 21h MOV AH,35H ;функция получения вектора MOV AL,21H ;номер вектора 21H INT 21H ;теперь сегмент в ES, смещение в BX mov cx,bx ;cx в bx lea bx,tbl ;в bx адресс начала таблицы lea si,res ;адрес результата -> si mov dx,si ;сохраняем адрес рез-та в регистре dx mov al,ch ;число для преобразования cbw ;преобразует байт в слово div del ;делим число на основание системы xlat ;преобразуем al в символ mov byte ptr [si],al ;сохранить в первом эл-те строки xchg ah,al ;обменять байты xlat mov byte ptr [si]+1,al ;сохранить al во втором эл-те строки mov ah,9h ;вывод на экран int 21h lea bx,tbl ;в bx адресс начала таблицы lea si,res ;адрес результата -> si mov dx,si ;сохраняем адрес рез-та в регистре dx mov al,cl ;число для преобразования cbw ;преобразует байт в слово div del ;делим число на основание системы xlat ;преобразуем al в символ mov byte ptr [si],al ;сохранить в первом эл-те строки xchg ah,al ;обменять байты xlat mov byte ptr [si]+1,al ;сохранить al во втором эл-те строки mov ah,9h ;вывод на экран int 21h mov ax,4c00h ;ф-ия завершения программы int 21h end start end