Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите пожалуйста! две ошибки в проге, асму считай не знаю 
:(
    Опции темы
Justaman
Дата 23.12.2002, 06:26 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


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
Дата 24.12.2002, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: нет
Всего: 18



"Исправленный" код:

Цитата

;
; Программа для подсчета числа слов в файле. Слова разделены
; пробелами, символами табуляции, возврата каретки или перевода
; строки.
;
; Вызов: 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 в значение числа
                                      ; считанных символов
NotControlZ:     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


Работает она так:

- запускаешь exe-файл;
- вводишь что-то, нажимая enter в конце каждого "слова";
- завешаешь ввод CTRL_Z;


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm: Общие вопросы"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0849 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.