Проблема с перехватом прерывания

Тема в разделе "WASM.ASSEMBLER", создана пользователем lukash, 15 сен 2006.

  1. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Помогите найти ошибку в этом коде:

    CSEG segment
    Assume es:CSEG, ds:CSEG

    org 100h

    begin:

    o_int dw ?
    s_int dw ?

    int_1c proc far

    pushf
    push ax
    push dx
    push di
    push es
    push ds

    mov ax,0B800h
    mov es,ax
    mov di,0

    mov ah,31
    mov al,1
    mov es:[di],ax

    pop ds
    pop es
    pop di
    pop dx
    pop ax
    popf

    jmp word ptr cs:o_int

    ret

    int_1c ENDP

    RES_END:

    set_vec proc

    mov ax,351ch
    int 21h
    mov o_int,bx
    mov s_int,es

    mov ax,251ch
    lea dx,int_1c
    int 21h

    ret

    set_vec endp

    lea ax,set_vec
    call ax

    lea dx,RES_END
    int 27h

    CSEG ends
    end begin

    Ведь после запуска должна остаться резидентной процедура обработки прерывания,
    и всегда должна выводится "рожица". А она выводится только один раз при запуске программы. Запускаю из под чистого ДОСа.
     
  2. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    А откуда, с твоей точки зрения, начинается исполнение кода?
     
  3. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Ещё вот тут ошибка:
    jmp word ptr cs:o_int
    Кто сказал что старый обработчик прерывания с новым в одном сегменте находится?
    Надо jmp dword ptr cs:[o_int ]
    Ну и как уже написали переменные в интересном месте у тебя находятся :)
    Больше сильно не вычитывал...
     
  4. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Да если бы только переменные. Там же и обработчик прерывания. Видимо, он при исполнении и выводит эту самую рожицу. После чего делает jmp по адресу cs:0.
     
  5. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    sergh
    исполнение кода должно начинаться с
    lea ax,set_vec
    call ax

    cppasm
    Про cs:[o_int ] знаю. Исправил, но все равно не работает.
    А где должны размещаться переменные? Или мои процедуры и переменные должны быть ниже начала исполнения кода?
     
  6. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Типичная ассемблерная программа заканчивается инструкцией:

    end <имя метки>

    Это не случайно. Исполнение начнётся с этой самой метки. Соответственно, у тебя оно начинается с begin.

    Кроме того, насколько я помню (вот тут могу ошибаться), в случае com-программ исполнение должно начинаться с самого начала текста, т.е. org 100, а сразу за ним - код. Поэтому данные и служебные подпрограммы, обработчики и прочее - в конец.
     
  7. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Дописал после begin:

    lea ax,main
    jmp ax

    Теперь код должен начинаться с

    main:

    lea ax,set_vec
    call ax

    но все виснет... Или я ошибаюсь?
     
  8. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Код (Text):
    1. mov ax,251ch
    2. lea dx,int_1c
    3. int 21h
    Откуда берётся сегмент кода, в котором расположен обработчик? Имхо, его нужно в es или ещё куда-то положить, точно не помню.
     
  9. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    mov ax,seg int_1c
    mov es,ax

    так написано в учебнике, но у меня ошибка про компилировании. Как обойти ошибку
    (Undefined symbol: int_1c)?
    Пока пишу так

    mov ax,cs
    mov es,ax

    ведь int_1c находится в cs
    если так то все равно виснет
     
  10. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Ура!!!
    Теперь все работает. Огромное всем спасибо!
    Просто разместил код в том порядке, в котором он должен выполнятся, а затем нерезидентную часть.