Turbo Assembler 3.0. Руководство пользователя

         

Пример анализа операционной среды DOS


С помощью функции EnvString вы сможете просмотреть операци- онную среду DOS и найти строку вида "s=НЕЧТО" и возвратить НЕЧТО, если это найдено.

DATA SEGMENT PUBLIC EXTRN prefixSeg : Word ; дает адрес PSP DATA ENDS SEGMENT PUBLIC ASSUME cs:CODE,ds:DATA

EnvString PROC FAR PUBLIC EnvString push bp cld ; работать в прямом ; направлении mov es,[prefixSeg] ; посмотреть PSP mov es,es:[2Ch] ; ES:DI указывают на ; операционную среду, xor di,di ; которая выровнена на ; границу параграфа mov bp,sp ; найти строку параметров, lds si,ss:[bp+6] ; которая следует за ; адресом возврата ASSUME ds:NOTHING lodsb ; посмотреть длину or al,al ; она равна 0? jz RetNul ; да, возврат mov ah,al ; в противном случае ; сохранить ее в AH mov dx,si ; DS:SI содержат указатель ; на первый параметр ; char xor al,al ; сделать его равным 0 Compare: mov ch,al ; мы хотим, чтобы для ; следующего отсчета ch=0 mov si,dx ; возвратить указатель на ; просмотренную строку mov cl,ah ; получить длину mov si,dx ; возвратить указатель на ; строку repe cmpsb ; сравнить байты jne Skip ; если сравнение неудач- ; ное попробовать следу- ; ющую строку cmp byte ptr es:[di],'=' ; сравнение ; завершилось успешно ; следующий символ '='? jne NoEqual ; если нет, все еще нет ; совпадения Found: mov ax,es ; DI:SI будет указывать ; на найденную нами строку mov ds,ax mov si,di inc si ; "пройти" символ '=' les bx,ss:[bp+10] ; получить адрес ; результата ; функции mov di,bx ; занести его в ES:DI inc di ; байт длины mov cl,255 ; задать максимальную ; длину CopyLoop: lodsb ; получить байт or al,al ; проверить на 0 jz Done ; если 0, выполнено stosb ; занести его в результат loop CopyLoop ; переместить до 255 ; байт Done: not cl ; при сохранении мы ; уменьшали от CL до 255 mov es:[bx],cl ; сохранить длину mov ax,SEG DATE mov ds,ax ; восстановить DS ASSUME ds:DATA pop bp ret 4 ASSUME ds:NOTHING Skip: dec di ; проверить на 0 NoEqual: mov cx,7FFFh ; длинный поиск, если ; нужно sub cx,di ; операционная среда ; никогда не превышает ; 32К jbe RetNul ; если конец, выйти repne scasb ; посмотреть следующий ; 0 jcxz RetNul ; выйти, если не найден cmp byte ptr es:[di],al ; второй 0 в строке? jne Compare ; если нет, попытаться ; снова RetNul: les di,ss:[bp+10] ; получить адрес ; результата stosb ; сохранить там 0 mov ax,SEG DATA mov ds,ax ; восстановить DS ASSUME ds:DATA pop bp ret 4 EnvString ENDP CODE ENDS END


Программа на Паскале, которая использует функцию EnvString, выглядит следующим образом:
program EnvTest; { программа ищет строки операционной среды }
var EnvVariable : string; EnvValue : string;
{$F+}
function EnvString(s:string) : string; external; {$L ENVSTRING.OBJ} {$F-} begin EnvVariable := 'PROMPT'; EnvValue := EnvString(EnvVariable); if EnvValue = '' then EnvValue := '*** не найдена ***'; Writeln('Переменная операционной среды: ', EnvVariable,' Значение: ',EnvValue); end.
Чтобы сформировать и запустить данные программы на Паскале и Ассемблере, используйте следующие команды командного файла:
TASM ENVSTR TPC ENVTEST ENVTEST
Если использовать директиву .MODEL, то функция EnvString на Ассемблере будет выглядеть следующим образом (ENVMOD.ASM):
.MODEL large, PASCAL .DATA EXTRN prefixSeg : Word ; дает адрес PSP .CODE EnvString PROC FAR EnvVar:DWORD RETURNS EnvVal:DWORD PUBLIC EnvString push bp cld ; работать в прямом ; направлении mov es,[prefixSeg] ; посмотреть PSP mov es,es:[2Ch] ; ES:DI указывают на ; операционную среду, xor di,di ; которая выровнена на ; границу параграфа mov bp,sp ; найти строку параметров, lds si,ss:[bp+6] ; которая следует за ; адресом возврата ASSUME ds:NOTHING lodsb ; посмотреть длину or al,al ; она равна 0? jz RetNul ; да, возврат mov ah,al ; в противном случае ; сохранить ее в AH mov dx,si ; DS:SI содержат указатель ; на первый параметр ; char xor al,al ; сделать его равным 0 Compare: mov ch,al ; мы хотим, чтобы для ; следующего отсчета ch=0 mov si,dx ; возвратить указатель на ; просмотренную строку mov cl,ah ; получить длину mov si,dx ; возвратить указатель на ; строку repe cmpsb ; сравнить байты jne Skip ; если сравнение неудач- ; ное, попробовать следу- ; ющую строку cmp byte ptr es:[di],'=' ; сравнение ; завершилось успешно ; следующий символ '='? jne NoEqual ; если нет, все еще нет ; совпадения Found: mov ax,es ; DI:SI будет указывать ; на найденную нами строку mov ds,ax mov si,di inc si ; "пройти" символ '=' les bx,ss:[bp+10] ; получить адрес ; результата функции mov di,bx ; занести его в ES:DI inc di ; байт длины mov cl,255 ; задать максимальную ; длину CopyLoop: lodsb ; получить байт or al,al ; проверить на 0 jz Done ; если 0, выполнено stosb ; занести его в результат loop CopyLoop ; переместить до 255 ; байт Done: not cl ; при сохранении мы ; уменьшали от CL до 255 mov es:[bx],cl ; сохранить длину mov ax,SEG DATE mov ds,ax ; восстановить DS ASSUME ds:DATA pop bp ret 4 ASSUME ds:NOTHING Skip: dec di ; проверять на 0 NoEqual: mov cx,7FFFh ; длинный поиск, если ; нужно sub cx,di ; операционная среда ; никогда не превышает ; 32К jbe RetNul ; если конец, выйти repne scasb ; посмотреть следующий ; 0 jcxz RetNul ; выйти, если не найден cmp byte ptr es:[di],al ; второй 0 в строке? jne Compare ; если нет, попытаться ; снова RetNul: les di,ss:[bp+10] ; получить адрес ; результата stosb ; сохранить там 0 mov ax,SEG DATA mov ds,ax ; восстановить DS ASSUME ds:DATA ret 4 EnvString ENDP CODE ENDS END
Вы можете использовать ту же программу на Паскале и просто ассемблировать альтернативный вариант функции EnvString и пере- компилировать программу с помощью того же командного файла.
Далее следует содержимое приложений.
Назад | Содержание | Вперед

Содержание раздела