помогите разобраться со смещением

Тема в разделе "WASM.BEGINNERS", создана пользователем slip11, 30 апр 2007.

  1. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    Пишется обработчик прерывания 09h. При нажатии на ctrl-alt-delete нужно, чтобы выводилось сообщение ctrlaltdelete. Так вот проблема в том что вместо этой строки выводится какой то бред. По моему проблема в смещении. Пробовал исправить но не получается. Вот исходник:

    Код (Text):
    1. .model tiny
    2. prg segment para public 'code'
    3. assume cs:prg,ss:prg,es:prg,ds:prg
    4. org 100h
    5.  
    6.     ctrl_key    equ     04h
    7.     alt_key     equ     08h
    8.     del_key     equ     53h
    9.     keyb_port   equ     60h
    10.    
    11.    
    12.     start:
    13.         jmp setup
    14.        
    15.         int9_handler proc far
    16.             sti
    17.             pushf
    18.             push es
    19.             push ax
    20.             push di
    21.            
    22.         L1:
    23.             mov ax,40h
    24.             mov es,ax
    25.             mov di,17h
    26.            
    27.             mov ah,es:[di]
    28.            
    29.         L2:
    30.             test ah,ctrl_key
    31.             jz L5
    32.            
    33.             test ah,alt_key
    34.             jz L5
    35.            
    36.         L3:
    37.             in al,keyb_port
    38.             cmp al,del_key
    39.             jne L5
    40.         L4:
    41.             and ah,not ctrl_key
    42.             mov es:[di],ah
    43.            
    44.             push ax
    45.             push di
    46.             push es
    47.            
    48.                                
    49.             xor ax,ax
    50.             mov ah,0Ch
    51.             mov si,offset message
    52.             mov bx,0B800h
    53.             mov es,bx
    54.             mov cx,13                             ;количество символов в строке
    55.             mov di,1987                           ;позиция вывода
    56.             cld
    57.             scr:
    58.                 lodsb
    59.                 stosw                  
    60.             loop scr
    61.  
    62.            
    63.             pop es
    64.             pop di
    65.             pop ax
    66.         L5:
    67.             pop di
    68.             pop ax
    69.             pop es
    70.             popf
    71.             jmp cs:[old_interrupt9]
    72.            
    73.         old_interrupt9  dd  ?
    74.         message db "ctrlaltdelete$"
    75.        
    76.         int9_handler endp
    77.        
    78.         end_ISR label byte
    79.        
    80.         setup:         
    81.             mov ax,3509h
    82.             int 21h
    83.            
    84.             mov word ptr old_interrupt9,bx
    85.             mov word ptr old_interrupt9+2,es
    86.            
    87.             mov ax,2509h
    88.             mov dx,offset int9_handler
    89.             int 21h
    90.            
    91.             mov ax,3100h
    92.            
    93.             mov dx,offset end_ISR
    94.             mov cl,4
    95.             shr dx,cl
    96.            
    97.             inc dx
    98.            
    99.             int 21h
    100.     prg ends
    101.     end start
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    slip11
    Не настроен сегмент message в регистр ds для команды lodsb.

    Почему начальный адрес вывода - 1987 - нечетный?
    Чтобы перед stosw не менять местами AL и AH?
    Тогда последний символ не получает атрибут.
     
  3. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    q_q

    Как настроить сегмент message в регистр ds? Писал такой код
    Код (Text):
    1. mov ax,seg message
    2. mov ds,ax
    выдает ошибку.
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Все верно, видеопамять немного по-другому устроена -- каждая ячейка описана двумя байтами, первый -- код символа, второй -- цвет символа и цвет фона. Соответственно строку надо подготовить так:

    message db "c", 0x7, "t", 0x7, "r", 0x7, "l", 0x7 ... и т.д.

    А саму запись строки в видеопамять можно оформить проще:

    Код (Text):
    1.     mov si,offset message
    2.     mov bx,0B800h
    3.     mov es,bx
    4.     mov cx,13                             ;количество символов в строке
    5.     mov di,1987                           ;позиция вывода
    6.     cld
    7.         rep movsb
     
  5. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    А лучше так
    Код (Text):
    1. ds:si->strimg
    2. es:di->videoRAM
    3. ah=атрибут
    4. cx=длина строки
    5. print:
    6. lodsb
    7. stosw
    8. loop print
    Тогда строка будет состоять только их символов. Конечно, если не надо чтобу ы каждого символа был свой атрибут.
     
  6. slip11

    slip11 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2007
    Сообщения:
    12
    Большое спасибо. Разобрался.