"Опыт дизассемблирования большой .com - программы" - читать интересную книгу автора (Крупник А.Б.)

sti ;06260 ;Turn ON Interrupts
b06261: cmp al,BYTE PTR es:d0046c ;06261
jz b06261 ;06266 ;Jump if equal (ZF=1)
mov al,BYTE PTR es:d0046c ;06268
dec cx ;0626c
jnz b06261 ;0626d ;Jump not equal(ZF=0)
pop ax ;0626f
out 61h,al ;06270 ;060-067:8024 keybrd contrlr
;
pop es ;06272
ret ;06273
s321 endp

Рис.6


При виде этого текста возникает догадка, что здесь идет зваимодействие с
областью данных BIOSa . Действительно, в регистр es засылается число 40,
т.е. es будет указывать на адрес 400 - начало этой области. Тогда следующий
вопрос - каков смысл адреса 046сh? Легко выяснить, что по этому адресу нахо-
дится счетчик прерываний от таймера. Если это так, то фрагмент, приведен-
ный на рис.6, обретает смысл - он дает задержку на число прерываний от тайме-
ра, заданное в регистре cx. Но если все сказанное верно, то d0046c должно быть
равно не 46сh, а просто 6сh! И действительно, если посмотреть подпрограмму s321
отладчиком, то станет ясно, что вместо mov al,BYTE PTR es:d0046c в тексте
должно стоять mov al,6ch.
Итак, чтобы исправить эту ошибку, необходимо:
1. Удалить из начала подпрограммы s12 присвоение d0046c equ 00046ch
2. Переписать приведенный на рис.6 фрагмент s321 следующим образом:

mov ax,0040h ;06257
;
mov es,ax ;0625a
mov al,BYTE PTR es:006ch ;0625c
sti ;06260 ;Turn ON Interrupts
b06261: cmp al,BYTE PTR es:006ch ;06261
jz b06261 ;06266 ;Jump if equal (ZF=1)
mov al,BYTE PTR es:006ch ;06268
dec cx ;0626c
jnz b06261 ;0626d ;Jump not equal(ZF=0)
pop ax ;0626f
out 61h,al ;06270 ;060-067:8024 keybrd contrlr
;
pop es ;06272
ret ;06273
s321 endp

Рассмотрим второй пример. В коде, выданном дизассемблером, встретился
такой кусок: