![]() |
|
![]() ![]() ![]() |
|
Justaman |
|
|||
Unregistered |
Вот код проги, компилятор турбо ассеблер 3.1
; ; Программа для подсчета числа слов в файле. Слова разделены ; пробелами, символами табуляции, возврата каретки или перевода ; строки. ; ; Вызов: wc < имя_файла.расш ; DOSSEG ; выбрать стандартный ; порядок сегментов .MODEL SMALL ; код и данные ; помещаются в 64К .STACK 200h ; стек размером 512 ; байт .DATA Count DW 0 ; используется для ; подсчета слов InWhitespace DB ? ; устанавливается в ; значение 1, когда ; последним прочитанным ; символов является ; разделитель TempChar DB ? ; временная память, ; используемая ; в GetNextCharacter Result DB 'Число слов: ', 5 DUP (?) ; строка, используемая ; для вывода результата CountInsertEnd LABEL BYTE ; используется для ; определения конца ; области, в которой ; хранится строка со ; значением счетчика DB 0dh,0ah,'$' ; функция DOS 9 ; работает со строками, ; которые завершаются ; символом $ .CODE ProgramStart: mov ax,@Data mov ds,ax ; DS указывает на ; сегмент данных mov [InWhitespace],1 ; предположим, это ; разделитель, так как ; первый отличный от ; разделителя символ, ; который мы найдем, ; будет отмечать начало ; слова CountLoop: call GetNextCharacter ; получить следующий ; символ для проверки, jz CountDone ; если он имеется call IsCharacterWhitespace ; это разделитель? jz IsWhitespace ; да cmp [InWhitespace],0 ; символ не является ; разделителем - теперь ; мы в разделителе? jz CountLoop ; мы не в разделителе ; и символ не является ; разделителем, поэтому ; с этим символом работа ; окончена inc [Count] ; мы в разделителе и ; символ не является ; разделителем, значит ; мы нашли начало нового ; слова mov [InWhitespace],0 ; отметить, что мы боль- ; ше не в разделителе jmp CountLoop ; обработать следующий ; символ IsWhitespace: mov [InWhitespace],1 ; отметить, что мы в ; разделителе jmp CountLoop ; обработать следующий ; символ ; ; Подсчет завершен - вывести результаты ; CountDone: mov ax,[Count] ; число, которое нужно ; преобразовать в строку mov bx,OFFSET CountInsertEnd-1 ; ссылка на ; конец строки, в ; которую нужно ; поместить число mov cx,5 ; число цифр, которые ; нужно преобразовать call ConvertNumberToString ; преобразовать ; число в строку mov bx,OFFSET Result ; ссылка на строку ; результата call PrintString ; вывести результат mov ah,4ch ; функция DOS ; завершения программы int 21h ; завершить программу ; ; Подпрограмма получения следующего символа из стандартного ; ввода ; ; Входные данные: нет ; ; Выходные данные: ; AL = символ, если он был доступен ; флаг Z = 0 (NZ), если символ доступен, ; = 1 (Z) при достижении конца строки ; ; Нарушаемые регистры: AH, BX, CX, DX ; GetNextCharacter PROC mov ah,3fh ; функция DOS ; чтения из файла mov bx,0 ; стандартный ; описатель ввода mov cx,1 ; считать один символ mov dx,OFFSET TempChar ; поместить символ ; в TempChar int 21h ; получить следующий ; символ jc NoCharacterRead ; если DOS сообщает ; об ошибке, ; интерпретировать ее, ; как конец файла cmp [TempChar],1ah ; это Control-Z? ; (метка конца файла) jne NotControlZ ; нет NoCharacterRead: sub ax,ax ; установить флаг Z, and ax,ax ; что отражает, был ; ли считан символ (NZ) ; или мы достигли ; конца файла (Z). ; Обратите внимание, ; что функция DOS 3fh ; устанавливает регистр ; AX в значение числа ; считанных символов mov al,[TempChar] ; возвратить считанный ; символ ret ; выполнено GetNextCharacter ENDP ; ; Подпрограмма, сообщающая, является ли прочитанный символ ; разделителем ; ; Входные данные: ; AL = проверяемому символу ; ; Выходные данные: ; флаг Z = 0 (NZ), если символ не является разделителем, ; = 1 (Z) если символ - разделитель ; ; Нарушаемые регистры: нет ; IsCharacterWhitespace PROC cmp al,09h ; это символ табуляции? jz EndIsCharacterWhitespace ; если да, то ; это разделитель cmp al,' ' ; это пробел? jz EndIsCharacterWhitespace ; если да, то ; это разделитель cmp al,0dh ; это возврат каретки? jz EndIsCharacterWhitespace ; если да, то ; это разделитель cmp al,0ah ; это перевод строки? cmp al,' ' ; это пробел? ; если да, то это ; разделитель, ; возвратить Z, если ; нет, то это не ; разделитель, возвратить ; NZ (устанавливаться ; cmp) EndIsCharacterWhiteSpace: ret IsCharacterWhiteSpace ENDP ; ; Подпрограмма, преобразующая двоичное число в текстовую ; строку ; ; Входные данные: ; AX = число, которое нужно преобразовать ; DS:BX = указатель на конец строки, в которой ; сохраняется текст ; ; Выходные данные: нет ; ; Нарушаемые регистры: AX, BX, CX, DX, SI ; ConvertNumberToString PROC mov si,10 ; используется в цикле ;ConvertLoop sub dx,dx ; преобразовать AX в ; двойное слово в AD:DX div si ; разделить число на 10 ; остаток - в DX, это ; десятичное число из ; одной цифры; число/10 ; находится в AX add dl,'0' ; преобразовать остаток ; в текстовую строку mov [bx],dl ; поместить эту цифру в ; строку dec bx ; ссылка на следующую ; самую значащую цифру loop ConvertLoop ; обработать следующую ; цифру, если она есть ret ConvertNumberToString ENDP ; ; Подпрограмма, выводящая строку на экран дисплея ; ; Входные данные: ; DS:BX = указатель на выводимую строку ; ; Выходные данные: нет ; ; Нарушаемые регистры: нет ; PrintString PROC push ax ; сохранение регистров push dx ; в подпрограмме mov ah,9 ; функция DOS вывода ; строки mov dx,bx ; установить DS:DX на ; выводимую строку int 21h ; вызвать DOS для ; вывода строки pop dx ; восстановить измененные pop ax ; регистры ret ; возврат управления PrintString ENDP END ProgramStart |
|||
|
||||
Chingachguk |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: нет Всего: 18 |
"Исправленный" код:
Работает она так: - запускаешь exe-файл; - вводишь что-то, нажимая enter в конце каждого "слова"; - завешаешь ввод CTRL_Z; -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Asm: Общие вопросы" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Asm: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |