• Как продвинуть сайт на первые места?
    Вы создали или только планируете создать свой сайт, но не знаете, как продвигать? Продвижение сайта – это не просто процесс, а целый комплекс мероприятий, направленных на увеличение его посещаемости и повышение его позиций в поисковых системах.
    Ускорение продвижения
    Если вам трудно попасть на первые места в поиске самостоятельно, попробуйте технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Если ни один запрос у вас не продвинется в Топ10 за месяц, то в SeoHammer за бустер вернут деньги.
    Начать продвижение сайта


  • Иллюстрированный самоучитель по SVGA

    Воспроизведение сжатых рисунков

    Подпрограмма распаковки строки

    Предположим, что в оперативной памяти задача зарезервировала пространство для размещения буфера общего назначения достаточно большого размера. Сегмент, в котором расположен буфер, хранится в переменной GenSeg, а начало свободного пространства в этом сегменте – в переменной GenOffs. Эти переменные должны располагаться в разделе данных программы в следующем порядке.

    GenOffs dw 0; адрес (смещение) в буфере общего назначения
    
    GenSeg dw 0; сегмент, содержащий буфер общего назначения
    

    Способы резервирования пространства в оперативной памяти описаны в приложении Б данной книги.

    Текст подпрограммы распаковки строки приведен в примере 3.24.

    Пример 3.24. Распаковка строки рисунка (способ RLE для PCX).

    Unpack: PushReg <ax,cx,dx,di,es>; сохранение содержимого регистров
    les di, Dword ptr GenOffs; смещение и сегмент буфера
    mov dx, fwidth; логический размер строки
    Unploop: call nxt sym; читаем в al следующий символ
    mov ex, 01; количество повторяемых символов
    cmp al, OCOh; символ содержит счетчик повторов?
    jbe Unl; › нет, это одиночный символ
    mov cl, al; копируем содержимое al в cl
    and cl, 3Fh; и выделяем количество повторов
    call nxt sym; читаем в al – повторяемый символ
    Unl: sub dx, ex; уменьшаем остаток строки
    rep stosb; записываем символы в буфер строки
    or dx, dx; строка распакована полностью?
    jnz Unploop; нет, продолжение распаковки
    PopReg <es, di, dx, ex, ax>; восстанавливаем регистры
    ret; › возврат из подпрограммы
    

    В примере 3.24 перед началом распаковки в стеке сохраняется содержимое используемых регистров. Затем команда les загружает в регистры es:di адрес для записи распакованной строки. Размер строки в байтах помещается в регистр dx, используемый в качестве счетчика распакованных символов. После этого выполняется цикл Unploop.

    Действия при распаковке соответствуют описанному выше алгоритму. Очередной байт считывается в регистр al, а в счетчик повторов сх записывается 1. Если код символа меньше чем сон, то происходит переход на метку ип_1. В противном случае в cl помещается содержимое 6-ти младших разрядов регистра al и читается повторяемый символ.

    Команда, имеющая метку un_i, вычитает из счетчика распакованных символов содержимое регистра сх. Следующая команда записывает в буфер строки содержимое регистра al столько раз, сколько указано в регистре сх. После этого проверяется содержимое регистра dx и если оно отлично от нуля, то цикл распаковки продолжается. В противном случае восстанавливается содержимое сохраненных в стеке регистров и выполняется команда возврата.

    Подпрограмма Nxtjsym

    Для получения кода очередного байта в примере 3.24 вызывается подпрограмма Nxtjsym, текст которой приведен в примере 3.25.

    Пример 3.25. Чтение очередного символа из буфера обмена.

    Nxt sym: cmp si, incount в буфере есть символы?
    jb @F › да, можно читать очередной символ
    push ex сохраняем содержимое сх
    mov ex, – I указываем размер порции данных
    call Readf читаем данные из файла
    mov incount, ax сохраняем размер порции данных
    xor si, si очищаем указатель адреса
    pop ex восстанавливаем содержимое сх
    @@: lods byte ptr fs: [si] чтение очередного байта
    ret; возврат из подпрограммы
    

    Подпрограмма примера 3.25 сравнивает текущее значение указателя адреса буфера обмена (содержимое регистра si) с переменной incount, значение которой соответствует размеру считанной из файла порции данных, т. е. количеству байтов, находящихся в буфере обмена.

    Если в буфере достаточно данных, то происходит переход на локальную метку @@. Для чтения кода символа в регистр al, увеличения указателя адреса на 1 и выхода из подпрограммы.

    Если достигнута граница данных, хранящихся в буфере обмена, то надо прочитать новую порцию данных. Для этого сохраняется содержимое регистра сх, в него записывается предельное количество байтов для чтения (-1 имеет код OFFFFh) и происходит обращение к подпрограмме Readf, описанной в примере 3.23.

    После чтения в переменную incount записывается количество прочитанных байтов, очищается регистр si и восстанавливается из стека содержимое регистра сх. Теперь можно прочитать очередной символ, увеличить значение сх на единицу и выйти из подпрограммы.

    В примере 3.25 отсутствует проверка состояния С-разряда регистра признаков после чтения. Вы можете включить ее в текст примера 3.25., но целесообразнее контролировать правильность чтения непосредственно в подпрограмме Readf. Это упростит структуру всех подпрограмм, которые обращаются к Readf.

    Замечание
    В литературе встречаются сведения о существовании файлов, частично не соответствующих стандарту фирмы ZSoft – при их сжатии цикл упаковки не прекращается в конце строки. Для распаковки подобных файлов подпрограмму примера 3.24 надо изменить так, чтобы она выдавала заданное количество распакованных кодов независимо от размера строки
    .

    Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.